【问题标题】:Merge dataframes based on regex condition根据正则表达式条件合并数据帧
【发布时间】:2017-07-26 16:07:26
【问题描述】:

这个问题涉及 R。我有两个数据帧,由这个最小的可重现示例表示:

a <- data.frame(geocode_selector = c("36005", "36047", "36061", "36081", "36085"), county_name = c("Bronx", "Kings", "New York", "Queens", "Richmond"))
b <- data.frame(geocode = c("360050002001002", "360850323001019"), jobs = c("4", "204"))

帮助传达我正在尝试执行的非常具体的操作的示例:数据框 a 中的 geocode_selector 列包含纽约五个行政区的 FIPS 县代码。数据框b 中的geocode 列是特定人口普查区块的15 位ID。 geocode 的前五位数字与更通用的 geocode_selector 匹配,表示人口普查块位于哪个县。我想在b 中添加一列,指定每个人口普查块属于哪个县,基于哪个@ b中的每个geocode与987654329@匹配。

一般来说,我正在尝试根据正则表达式条件合并数据帧。理想情况下,我想执行一个完整的合并,将a 的所有列转移到b 而不仅仅是county_name

我尝试了一些类似的东西:

b[, "county_name"] <- NA
for (i in 1:nrow(b)) {
  for (j in 1:nrow(a)) {.
    if (grepl(data.a$geocode_selector[j], b$geocode[i]) == TRUE) {
      b$county_name[i] <- a$county_name[j]
    }
  }
}

但是我实际处理的大型数据集花了很长时间,成品不是我想要的。

任何关于如何根据正则表达式条件有条件地合并数据帧的见解将不胜感激。

【问题讨论】:

  • if (… == TRUE) 是无意义的代码:只需写 if (…),不需要永远== TRUE:这实际上是 if 已经在做的事情。

标签: r regex dataframe


【解决方案1】:

你可以这样做...

b$geocode_selector <- substr(b$geocode,1,5)
b2 <- merge(b, a, all.x=TRUE) #by default it will merge on common column names

b2
  geocode_selector         geocode jobs county_name
1            36005 360050002001002    4       Bronx
2            36085 360850323001019  204    Richmond

如果您愿意,可以使用b2[,1] &lt;- NULLb2 中删除geocode_selector

【讨论】:

    【解决方案2】:

    我们可以使用sub来创建'geocode_selector'然后进行join

    library(data.table)
    setDT(a)[as.data.table(b)[, geocode_selector := sub('^(.{5}).*', '\\1', geocode)], 
                         on = .(geocode_selector)]
    #   geocode_selector county_name         geocode jobs
    #1:            36005       Bronx 360050002001002    4
    #2:            36085    Richmond 360850323001019  204
    

    【讨论】:

      【解决方案3】:

      这是使用 dplyr 的绝佳机会。我也比较喜欢stringr中的字符串处理函数,比如str_sub


      library(dplyr)
      library(stringr)
      
      a <- data_frame(geocode_selector = c("36005", "36047", "36061", "36081", "36085"), 
                      county_name = c("Bronx", "Kings", "New York", "Queens", "Richmond"))
      b <- data_frame(geocode = c("360050002001002", "360850323001019"), 
                      jobs = c("4", "204"))
      
      b %>%
        mutate(geocode_selector = str_sub(geocode, end = 5)) %>%
        inner_join(a, by = "geocode_selector")
      #> # A tibble: 2 x 4
      #>           geocode  jobs geocode_selector county_name
      #>             <chr> <chr>            <chr>       <chr>
      #> 1 360050002001002     4            36005       Bronx
      #> 2 360850323001019   204            36085    Richmond
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-01
        • 1970-01-01
        • 2017-12-30
        • 1970-01-01
        • 1970-01-01
        • 2021-06-04
        相关资源
        最近更新 更多