Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex R-在邮政编码字符串中插入可变数量的空格_Regex_R_Dplyr_Postal Code - Fatal编程技术网

Regex R-在邮政编码字符串中插入可变数量的空格

Regex R-在邮政编码字符串中插入可变数量的空格,regex,r,dplyr,postal-code,Regex,R,Dplyr,Postal Code,我有一套英国邮政编码,需要重新格式化。它们由incode和outcode组成,其中incode的形式为“数字字母字母”,例如2DB,outcode是2到4个字母和数字的组合,例如NW1或SW10或EC1A 目前,incode和outcode之间有一个空格,但我需要重新格式化这些空格,以便完整的邮政编码为7个字符长,例如:(“-”代表空格) NW1-2DB->NW1-2DB(输出代码和输入代码之间有1个空格) SW10-9NH->SW109NH(0个空间) E1-6QL->E1--6QL(2个空

我有一套英国邮政编码,需要重新格式化。它们由incode和outcode组成,其中incode的形式为“数字字母字母”,例如2DB,outcode是2到4个字母和数字的组合,例如NW1或SW10或EC1A

目前,incode和outcode之间有一个空格,但我需要重新格式化这些空格,以便完整的邮政编码为7个字符长,例如:(“-”代表空格)

  • NW1-2DB->NW1-2DB(输出代码和输入代码之间有1个空格)
  • SW10-9NH->SW109NH(0个空间)
  • E1-6QL->E1--6QL(2个空格)
数据:

但是得到这个错误:

错误:无效的“times”参数

没有创建邮政编码7的最后一步,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%
突变(outcode=gsub('?(\\S+\\S*\\d\\w{2}$','\\1',邮政编码),
incode=gsub('\\S+\\S*?(\\d\\w{2})$','\\1',邮政编码))%>%
突变(输出长度=nchar(输出代码))%>%
突变(邮政编码7=粘贴0(输出代码,
粘贴0(rep(“,4),collapse=”“),
国际编码)
df
#邮政编码输出代码输入代码输出长度邮政编码7
#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()
接受一列作为mutate中的times参数?或者我应该考虑一种完全不同的方法


编辑:我刚刚意识到,我可以对输出代码中的每一个2个字符、3个字符或4个字符使用
if
语句,但这感觉不是很优雅。

看看
stringr
包中的
stru\u-pad
方法,它适合您的情况:

library(stringr)
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 = paste(outcode, str_pad(incode, 7-out_length), sep = ""))

df
#   postcode outcode incode out_length postcode7
# 1  NW1 2DB     NW1    2DB          3   NW1 2DB
# 2 SW10 9NH    SW10    9NH          4   SW109NH
# 3   E1 6QL      E1    6QL          2   E1  6QL
库(stringr)
df%
突变(outcode=gsub('?(\\S+\\S*\\d\\w{2}$','\\1',邮政编码),
incode=gsub('\\S+\\S*?(\\d\\w{2})$','\\1',邮政编码))%>%
突变(输出长度=nchar(输出代码))%>%
变异(邮政编码7=粘贴(输出代码,字符串填充(输入代码,7-out长度),sep=”“)
df
#邮政编码输出代码输入代码输出长度邮政编码7
#1 NW1 2DB NW1 2DB 3 NW1 2DB
#2 SW10 9NH SW10 9NH 4 SW109NH
#3 E1 6QL E1 6QL 2 E1 6QL

使用str_pad和分离:

library(dplyr)
library(tidyr)
library(stringr)

df %>% 
  separate(postcode, into = c("incode", "outcode"), remove = FALSE) %>% 
  mutate(
    postcode8 = paste0(incode,
                       str_pad(outcode,
                               8 - nchar(incode), side = "left", pad = " ")))

#   postcode incode outcode postcode8
# 1  NW1 2DB    NW1     2DB  NW1  2DB
# 2 SW10 9NH   SW10     9NH  SW10 9NH
# 3   E1 6QL     E1     6QL  E1   6QL

另一种解决方案是,使用
sprintf
格式化输出,使用
tidyr::extract
进行匹配。这样做的优点是大大简化了填充的模式和代码:

df %>%
    extract(postcode, into = c('out', 'in'), '(\\S{2,4})\\s*(\\d\\w\\w)') %>%
    mutate(postcode = sprintf('% -4s%s', out, `in`))

我确实喜欢上面发布的
分离版
,但它要求邮政编码都用空格分隔。根据我的经验,通常情况并非如此。

您是否必须使用正则表达式来拆分邮政编码?
strsplit
有什么问题?@Psidom默认情况下,
strsplit
也使用正则表达式-但问题是
strsplit
需要一些东西来拆分。如果你查看OP的正则表达式,你会发现中间的空间在输入中完全是可选的。你是正确的,<代码> StruSts/Code >,只要在代码和代码之间有一个空间(如我所指定的),但是Konrad是正确的,因为邮政编码不总是这样格式化的。我的问题太具体了,这不好。@KonradRudolph OK。我正在读OP的声明,因为目前在incode和outcode之间有一个空格。没有仔细查看正则表达式。这是有道理的。该代码通常不起作用,它要求(a)至少有一个空格分隔邮政编码组,以及(b)数据框至少包含一个已正确格式化的邮政编码;否则,理由就行不通了。
df%>%mutate(Postcode7=paste0(format(gsub('\\s.*$','',postcode),justify='left'),
                        format(gsub('^\\S+\\s','',postcode),justify='right')))
library(stringr)
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 = paste(outcode, str_pad(incode, 7-out_length), sep = ""))

df
#   postcode outcode incode out_length postcode7
# 1  NW1 2DB     NW1    2DB          3   NW1 2DB
# 2 SW10 9NH    SW10    9NH          4   SW109NH
# 3   E1 6QL      E1    6QL          2   E1  6QL
library(dplyr)
library(tidyr)
library(stringr)

df %>% 
  separate(postcode, into = c("incode", "outcode"), remove = FALSE) %>% 
  mutate(
    postcode8 = paste0(incode,
                       str_pad(outcode,
                               8 - nchar(incode), side = "left", pad = " ")))

#   postcode incode outcode postcode8
# 1  NW1 2DB    NW1     2DB  NW1  2DB
# 2 SW10 9NH   SW10     9NH  SW10 9NH
# 3   E1 6QL     E1     6QL  E1   6QL
df %>%
    extract(postcode, into = c('out', 'in'), '(\\S{2,4})\\s*(\\d\\w\\w)') %>%
    mutate(postcode = sprintf('% -4s%s', out, `in`))
df%>%mutate(Postcode7=paste0(format(gsub('\\s.*$','',postcode),justify='left'),
                        format(gsub('^\\S+\\s','',postcode),justify='right')))