【问题标题】:Conditionally assign column value based on partial match to at least 1 element in vector基于部分匹配有条件地将列值分配给向量中的至少 1 个元素
【发布时间】:2016-02-16 18:54:48
【问题描述】:

我有 2 个数据框

market<-c('New York, NY','Some place in Chicago','Lala land')
d1<-as.data.frame(market)
metro<-c('Chicago','Meow','New York')
d2<-as.data.frame(metro)

d2$metro 区域可以在d1$market 中找到时,我需要创建另一列d2$inmarket 为1,否则为0。我的目标是让d2 看起来像这样:

     metro inmarket
1  Chicago        1
2     Meow        0
3 New York        1

我已经探索了 grepsqldf 选项,但我没有看到任何回答我的问题。

This 会在匹配的地方返回d1 的索引,但我需要d2 的索引才能分配值1 或0。

我也可以使用sqldf 来选择d1 中匹配的行,但我不能反过来,因为我无法在d2$metro 中搜索d1$market,显然.

d1$market<-as.character(d1$market)
d2$metro<-as.character(d2$metro)
find<-function(x){fn$sqldf("select market from d1 where market like '%$x%'")}
p<-d2$metro
m<-lapply(p,function(y) find(y))
data.frame(matrix(unlist(m)))
    1 Some place in Chicago
    2 New York, NY

有什么想法吗?

编辑:这适用于一个元素,但我需要循环:

d2$inmarket[grepl('Chicago', d1$market)] <- 1

【问题讨论】:

  • 可以试试library(data.table) ; setDT(d2)[, inmarket := +any(grepl(metro, d1$market, fixed = TRUE)), by = metro] 之类的东西。
  • 你可以试试+(d2$metro %in% gsub(paste0('.*(', paste(d2$metro, collapse='|'), ').*'), '\\1', d1$market))
  • @DavidArenburg fixed = TRUE 是干什么用的?

标签: regex r apply sqldf


【解决方案1】:

一种选择是在 'd1' 中对 'market' 列进行子串化并使用 %in%

d2$inmarket <- +(d2$metro %in% gsub(paste0('.*(', paste(d2$metro, 
        collapse='|'), ').*'), '\\1', d1$market))
d2
#     metro inmarket
#1  Chicago        1
#2     Meow        0
#3 New York        1

【讨论】:

  • 这是一个不错的方法,但如果 df$metro 是一个大向量,它可能会变得一团糟,因为 gsub/grep* 函数的模式参数大小有限制。
  • @DavidArenburg 你是对的。另一种选择是library(stringi);sapply(d2[,1], function(x) any(stri_detect_fixed(d1[,1],x)))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-16
  • 1970-01-01
  • 2021-11-18
  • 2012-01-05
  • 1970-01-01
  • 2020-06-28
相关资源
最近更新 更多