将 Dataframe 字符串列解析为街道、城市、州和邮政编码
Parse Dataframe string column into Street, City, State & Zip code
我正在尝试将以下固定字符串分成几列,如街道、城市、州和邮政编码。是否可以通过 INSTR & Subtr 方法在 SQLDF 中执行此操作?
示例地址字符串。困难的部分是 NV 和邮政编码解析。
727 Wright Brothers Ln, Las Vegas, NV 89119, USA
我能够使用 sqldf/instr 解析 city/street 信息,但无法解析 state/zip 代码
的最后两个值
parsed_tweetAddressdf <- sqldf("SELECT lon, lat, result, substr(result,0,instr(result,',')) AS street, substr(result,instr(result,',')+1,instr(result,',')-1) AS city from tweetAddressdf")
这里有一些备选方案。他们都按照问题的要求使用 instr
和 substr
,尽管第三个也写出数据并将其读回(除了使用 instr
和 substr
)。最后的注释指出,在普通 R 中或在 gsubfn.
中使用 read.pattern
也很容易做到这一点
1) 假设 state, zip 和 country 字段的宽度是固定的 只有一个样本记录不可能知道你的一般情况是什么但是如果我们假设每条记录结束在 SS ZZZZZ, USA
中,SS 是两个字母的州缩写,ZZZZZ 是 5 位数字的邮政编码,那么这有效:
DF <- data.frame(v = "727 Wright Brothers Ln, Las Vegas, NV 89119, USA")
library(sqldf)
sqldf("select
substr(v, 0, instr(v, ',')) street,
substr(v, instr(v, ',') + 2, length(v) - 16 - instr(v, ',')) city,
substr(v, -13, 2) state,
substr(v, -10, 5) zip
from DF")
给予:
street city state zip
1 727 Wright Brothers Ln Las Vegas NV 89119
2) 严格基于逗号分隔(state/zip除外) 这种方法以额外的复杂性为代价避免了 (1) 中的某些假设。它采用前两个逗号分隔的字段、2 个字符的状态以及之后的所有内容到下一个逗号作为 zip。
它使用三重嵌套 select。最里面的 select 表示 a
将输入字符串解析为:street
和 a.rest
。下一个向外进行表示b
returns street
已经从a
解析,并将a.rest
解析为city
和b.rest
.最外层的 returns street
和 city
已经解析加上它 returns b.rest
中的两个状态字符以及 b.rest
中超出它们的所有内容下一个逗号为 zip
.
library(sqldf)
sqldf("
select
street,
city,
substr(b.rest, 1, 2) state,
substr(b.rest, 4, instr(b.rest, ',') - 4) zip
from (
select
street,
substr(a.rest, 0, instr(a.rest, ',')) city,
substr(a.rest, instr(a.rest, ',') + 2) rest
from (select
substr(v, 0, instr(v, ',')) street,
substr(v, instr(v, ',') + 2) rest
from DF) a) b
")
给予:
street city state zip
1 727 Wright Brothers Ln Las Vegas NV 89119
3) read.csv.sql 如果可以把它写出来再读回来,那么我们可以使用 read.csv.sql
,一个围绕 [=41 的包装器=].虽然题目没问,但是这个也解析出国:
write.table(DF, "addresses.csv", row.names = FALSE, col.names = FALSE,
sep = ",", quote = FALSE)
read.csv.sql("addresses.csv", header = FALSE, sql =
"select V1 street,
V2 city,
substr(V3, 2, 2) state,
substr(V3, 4) zip,
V4 country
from file")
给予:
street city state zip country
1 727 Wright Brothers Ln Las Vegas NV 89119 USA
注 1:这在普通 R 中也很容易。
dd <- read.table(text = as.character(DF$v), sep = ",",
col.names = c("street", "city", "state_zip", "country"))
transform(dd,
state = substring(state_zip, 2, 3),
zip = substring(state_zip, 4))[c(1, 2, 5, 6, 4)]
给予:
street city state zip country
1 727 Wright Brothers Ln Las Vegas NV 89119 USA
注 2: 使用 gsubfn 中的 read.pattern
更容易:
library(gsubfn)
pat <- "(.*), (.*), (..) (.*), (.*)"
read.pattern(text = as.character(DF$v), pattern = pat,
col.names = c("street", "city", "state", "zip", "country"))
给予:
street city state zip country
1 727 Wright Brothers Ln Las Vegas NV 89119 USA
我正在尝试将以下固定字符串分成几列,如街道、城市、州和邮政编码。是否可以通过 INSTR & Subtr 方法在 SQLDF 中执行此操作?
示例地址字符串。困难的部分是 NV 和邮政编码解析。
727 Wright Brothers Ln, Las Vegas, NV 89119, USA
我能够使用 sqldf/instr 解析 city/street 信息,但无法解析 state/zip 代码
的最后两个值parsed_tweetAddressdf <- sqldf("SELECT lon, lat, result, substr(result,0,instr(result,',')) AS street, substr(result,instr(result,',')+1,instr(result,',')-1) AS city from tweetAddressdf")
这里有一些备选方案。他们都按照问题的要求使用 instr
和 substr
,尽管第三个也写出数据并将其读回(除了使用 instr
和 substr
)。最后的注释指出,在普通 R 中或在 gsubfn.
read.pattern
也很容易做到这一点
1) 假设 state, zip 和 country 字段的宽度是固定的 只有一个样本记录不可能知道你的一般情况是什么但是如果我们假设每条记录结束在 SS ZZZZZ, USA
中,SS 是两个字母的州缩写,ZZZZZ 是 5 位数字的邮政编码,那么这有效:
DF <- data.frame(v = "727 Wright Brothers Ln, Las Vegas, NV 89119, USA")
library(sqldf)
sqldf("select
substr(v, 0, instr(v, ',')) street,
substr(v, instr(v, ',') + 2, length(v) - 16 - instr(v, ',')) city,
substr(v, -13, 2) state,
substr(v, -10, 5) zip
from DF")
给予:
street city state zip
1 727 Wright Brothers Ln Las Vegas NV 89119
2) 严格基于逗号分隔(state/zip除外) 这种方法以额外的复杂性为代价避免了 (1) 中的某些假设。它采用前两个逗号分隔的字段、2 个字符的状态以及之后的所有内容到下一个逗号作为 zip。
它使用三重嵌套 select。最里面的 select 表示 a
将输入字符串解析为:street
和 a.rest
。下一个向外进行表示b
returns street
已经从a
解析,并将a.rest
解析为city
和b.rest
.最外层的 returns street
和 city
已经解析加上它 returns b.rest
中的两个状态字符以及 b.rest
中超出它们的所有内容下一个逗号为 zip
.
library(sqldf)
sqldf("
select
street,
city,
substr(b.rest, 1, 2) state,
substr(b.rest, 4, instr(b.rest, ',') - 4) zip
from (
select
street,
substr(a.rest, 0, instr(a.rest, ',')) city,
substr(a.rest, instr(a.rest, ',') + 2) rest
from (select
substr(v, 0, instr(v, ',')) street,
substr(v, instr(v, ',') + 2) rest
from DF) a) b
")
给予:
street city state zip
1 727 Wright Brothers Ln Las Vegas NV 89119
3) read.csv.sql 如果可以把它写出来再读回来,那么我们可以使用 read.csv.sql
,一个围绕 [=41 的包装器=].虽然题目没问,但是这个也解析出国:
write.table(DF, "addresses.csv", row.names = FALSE, col.names = FALSE,
sep = ",", quote = FALSE)
read.csv.sql("addresses.csv", header = FALSE, sql =
"select V1 street,
V2 city,
substr(V3, 2, 2) state,
substr(V3, 4) zip,
V4 country
from file")
给予:
street city state zip country
1 727 Wright Brothers Ln Las Vegas NV 89119 USA
注 1:这在普通 R 中也很容易。
dd <- read.table(text = as.character(DF$v), sep = ",",
col.names = c("street", "city", "state_zip", "country"))
transform(dd,
state = substring(state_zip, 2, 3),
zip = substring(state_zip, 4))[c(1, 2, 5, 6, 4)]
给予:
street city state zip country
1 727 Wright Brothers Ln Las Vegas NV 89119 USA
注 2: 使用 gsubfn 中的 read.pattern
更容易:
library(gsubfn)
pat <- "(.*), (.*), (..) (.*), (.*)"
read.pattern(text = as.character(DF$v), pattern = pat,
col.names = c("street", "city", "state", "zip", "country"))
给予:
street city state zip country
1 727 Wright Brothers Ln Las Vegas NV 89119 USA