Sql 将Dataframe字符串列解析为Street、City、State和amp;邮政编码
我正在尝试将下面的固定字符串拆分为几个列,如街道、城市、州和邮政编码。是否可以通过INSTR&Subtr方法在SQLDF中执行此操作 示例地址字符串。困难的部分是NV和邮政编码解析Sql 将Dataframe字符串列解析为Street、City、State和amp;邮政编码,sql,r,sqldf,Sql,R,Sqldf,我正在尝试将下面的固定字符串拆分为几个列,如街道、城市、州和邮政编码。是否可以通过INSTR&Subtr方法在SQLDF中执行此操作 示例地址字符串。困难的部分是NV和邮政编码解析 727 Wright Brothers Ln, Las Vegas, NV 89119, USA 我能够使用sqldf/instr解析城市/街道信息,但无法解析state/zip代码的最后两个值 parsed_tweetAddressdf <- sqldf("SELECT lon, lat, result,
727 Wright Brothers Ln, Las Vegas, NV 89119, USA
我能够使用sqldf/instr解析城市/街道信息,但无法解析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)假设州、邮政编码和国家/地区字段是固定宽度的,只有一个样本记录,不可能知道您的一般情况,但如果我们假设每个记录都以SS ZZZZ,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")
2)严格按照逗号分隔(state/zip除外)这种方法避免了(1)中的某些假设,但会增加复杂性。它将前两个逗号分隔的字段、两个字符的状态以及之后的所有内容作为zip文件,并将下一个逗号作为zip文件
它使用三重嵌套选择。最里面的select表示为a
将输入字符串解析为:street
和a.rest
。下一个向外进行的代码表示为b
返回已从a
解析的street
,并将a.rest
解析为city
和b.rest
。最外面的一个返回已解析的街道
和城市
,再加上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
street city state zip
1 727 Wright Brothers Ln Las Vegas NV 89119
street city state zip country
1 727 Wright Brothers Ln Las Vegas NV 89119 USA
street city state zip country
1 727 Wright Brothers Ln Las Vegas NV 89119 USA
street city state zip country
1 727 Wright Brothers Ln Las Vegas NV 89119 USA
3)read.csv.sql如果可以写出并读回,那么我们可以使用read.csv.sql
,这是一个围绕sqldf
的包装器。虽然这个问题并没有要求它,但这个问题也剖析了这个国家:
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
1 727 Wright Brothers Ln Las Vegas NV 89119
street city state zip
1 727 Wright Brothers Ln Las Vegas NV 89119
street city state zip country
1 727 Wright Brothers Ln Las Vegas NV 89119 USA
street city state zip country
1 727 Wright Brothers Ln Las Vegas NV 89119 USA
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)]
注2:使用gsubfn中的read.pattern
更容易:
library(gsubfn)
pat <- "(.*), (.*), (..) (.*), (.*)"
read.pattern(text = as.character(DF$v), pattern = pat,
col.names = c("street", "city", "state", "zip", "country"))
你已经试过什么了?你在哪里卡住了?寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。请看:。你想要的结果是什么?更新了初始问题的主体我认为使用正则表达式会容易得多(这可以很容易地捕捉到一个事实,例如州代码是两个字母,邮政编码是5个数字),如果你发布
dput(head(parsed_tweetAddressdf))
的结果,可能会有一些希望,但目前,你是唯一一个能够运行代码并有可能获得价值的人。添加了解决方案和注释。