R查找以一组数字字符开头的行



我正在尝试使用前两个前缀修复邮政编码输入错误。作为一个可重复的例子,(假设(假设邮政编码以01、02、03和04开头是MA,但我的数据包含以下错误。

ma_zip <- c("01", "02", "03", "04")
df <- data.frame(zip = c("01100", "02223", "04332", "03234"),
state = c("MA", "NJ", "NY", "NY")) %>%
mutate(zip = as.character(zip),
state = as.character(state))

我试着用以下两种方法来纠正这个错误。在第一种(也是蛮力(方法中,我逐一修复了它,并得到了我想要的结果。

df_cleaned1 <- df %>%
mutate(state = replace(state, startsWith(zip, "02"), "MA"),
state = replace(state, startsWith(zip, "03"), "MA"),
state = replace(state, startsWith(zip, "04"), "MA"))
> df_cleaned1
zip state
1 01100    MA
2 02223    MA
3 04332    MA
4 03234    MA

但这并不是最有趣的事情,因为我必须反复复制和粘贴。因此,我尝试了以下操作,但似乎不起作用(也没有抛出错误消息(。

df_cleaned2 <- df %>%
mutate(state = replace(state, startsWith(zip, paste(ma_zip, collapse="|")), "MA"))
> df_cleaned2
zip state
1 01100    MA
2 02223    NJ
3 04332    NY
4 03234    NY

有没有一种有效的方法来产生df_cleaned1,同时避免暴力方法?(不必使用startWith功能(

我们可以使用stringr中的str_sub来获取前2个字符,并将其与%in%一起使用

library(dplyr)
library(stringr)
df %>%
mutate(state = replace(state, str_sub(zip, 1, 2) %in% ma_zip,
'MA'))

或者另一个选项是regex

df %>%
mutate(state = replace(state, str_detect(zip, str_c("^(", str_c(ma_zip, collapse="|"), ")")), 'MA'))
#   zip state
#1 01100    MA
#2 02223    MA
#3 04332    MA
#4 03234    MA

也许:

library(dplyr)
df %>% mutate(state = replace(state, substr(zip, 1, 2) %in% ma_zip, 'MA'))

输出:

zip state
1 01100    MA
2 02223    MA
3 04332    MA
4 03234    MA

以下是一些基本的R解决方案

df <- within(df, state <- replace(state,gsub("(\w{2}).*","\1",zip) %in% ma_zip,"MA"))

df <- within(df, state <- replace(state,substr(zip,1,2) %in% ma_zip,"MA"))

使得

> df
zip state
1 01100    MA
2 02223    MA
3 04332    MA
4 03234    MA

另一个选项是使用grepl而不是startsWith。您将需要创建以下模式^01|^02|^03|^04,这可以使用粘贴函数完成,并对您的方法进行一些修改(@qnp1521(:

df_cleaned2 <- df %>% mutate(state = replace(state, grepl(paste("^",ma_zip, collapse ="|",sep=""),zip), "MA"))

df_cleaned2
1 01100    MA
2 02223    MA
3 04332    MA
4 03234    MA

最新更新