【发布时间】:2016-11-01 12:16:41
【问题描述】:
我有一组需要重新格式化的英国邮政编码。它们由一个 incode 和一个 outcode 组成,其中 incode 的形式是“数字字母字母”,例如2DB 和 outcode 是 2 到 4 个字母和数字的组合,例如NW1 或 SW10 或 EC1A
目前 incode 和 outcode 之间有一个空格,但我需要重新格式化这些,以便完整的邮政编码为 7 个字符长,例如:('-' 代表空格)
- NW1-2DB -> NW1-2DB(outcode 和 incode 之间有 1 个空格)
- SW10-9NH -> SW109NH(0 个空格)
- E1-6QL -> E1--6QL(2 个空格)
数据:
df <- data.frame("postcode"=c("NW1 2DB","SW10 9NH","E1 6QL"))
df
# postcode
# 1 NW1 2DB
# 2 SW10 9NH
# 3 E1 6QL
我已经编写了一个正则表达式字符串来分隔 outcode 和 incode,但找不到在它们之间添加可变数量空格的方法(此示例只是在 outcode 和 incode 之间创建两个空格)。
require(dplyr)
df <- df %>% mutate(postcode_2sp = gsub('?(\\S+)\\s*?(\\d\\w{2})$','\\1 \\2', postcode)
为了解决这个问题,我尝试使用 mutate()、nchar() 和 rep():
df<-df %>%
mutate(outcode=gsub('?(\\S+)\\s*\\d\\w{2}$','\\1',postcode),
incode=gsub('\\S+\\s*?(\\d\\w{2})$','\\1',postcode)) %>%
mutate(out_length=nchar(outcode))%>%
mutate(postcode7=paste0(outcode,
paste0(rep(" ",4-out_length),collapse=""),
incode))
但得到这个错误:
错误:'times' 参数无效
没有创建 postcode7 的最后一步,df 如下所示:
df
# postcode outcode incode out_length
# 1 NW1 2DB NW1 2DB 3
# 2 SW10 9NH SW10 9NH 4
# 3 E1 6QL E1 6QL 2
如果我将 rep 'times' 参数设置为常量,代码会按预期运行(但不会执行我需要它执行的操作!)
df<-df %>%
mutate(outcode=gsub('?(\\S+)\\s*\\d\\w{2}$','\\1',postcode),
incode=gsub('\\S+\\s*?(\\d\\w{2})$','\\1',postcode)) %>%
mutate(out_length=nchar(outcode))%>%
mutate(postcode7=paste0(outcode,
paste0(rep(" ",4),collapse=""),
incode))
df
# postcode outcode incode out_length postcode7
# 1 NW1 2DB NW1 2DB 3 NW1 2DB
# 2 SW10 9NH SW10 9NH 4 SW10 9NH
# 3 E1 6QL E1 6QL 2 E1 6QL
有没有办法让rep() 接受一个列作为变异中的 times 参数?还是我应该寻找一种完全不同的方法?
编辑:我刚刚意识到,对于输出代码中 2 个字符、3 个字符或 4 个字符的每种情况,我都可以使用 if 语句,但这感觉不是很优雅。
【问题讨论】:
-
您必须使用正则表达式来拆分您的邮政编码吗?
strsplit有什么问题? -
@Psidom 默认情况下,
strsplit也使用正则表达式——但问题是strsplit需要something 来拆分。如果您查看 OP 的正则表达式,您会发现中间的空格在输入中完全是可选的。 -
你是对的,
strsplit只要在 incode 和 outcode 之间有空格(正如我所指定的)就可以工作,但 Konrad 是正确的,因为邮政编码并不总是这样格式化。我的问题太具体了。 -
@KonradRudolph 好的。我正在阅读 OP 的声明,因为 目前在 incode 和 outcode 之间有一个空格。没有很仔细地看正则表达式。这是有道理的。
标签: regex r dplyr postal-code