【问题标题】:R partial match in data frame数据框中的R部分匹配
【发布时间】:2013-05-03 17:04:52
【问题描述】:

如何解决数据框中的部分匹配问题? 可以说这是我的df df

   V1  V2  V3 V4
1 ABC 1.2 4.3  A
2 CFS 2.3 1.7  A
3 dgf 1.3 4.4  A

并且我想添加一个包含数字 111 的列 V5,仅当 V1 中的值在名称中包含“f”时,以及仅当 V1 中的值包含“gf”时才添加数字 222。我会因为几个值包含“f”而遇到问题 - 还是我发出命令的顺序会处理它?

我尝试了类似的方法:

df$V5<- ifelse(df$V1 = c("*f","*gf"),c=(111,222) )

但它不起作用。

主要问题是如何告诉 R 寻找“部分匹配”?

感谢您的帮助!

【问题讨论】:

  • ifelse 并没有那么多“洞察力”。 R 中的“=”符号用于分配,而不是用于测试,并且它不支持“内部”级别的分支逻辑。
  • 只是给你一个想法:你可以这样使用ifelseifelse(grepl("gf", df$V1), 222, ifelse(grepl("f", df$V1), 111, NA))But I suspect it might be a tad slower.
  • ifelse 构造的优点是可以简单地分配它,而无需预先将 V5 的值指定为 NA。

标签: r match partial


【解决方案1】:

除了为"f", "gf", ... 设置序列值的解决方案之外,值得看看零宽度前瞻/后视的正则表达式功能。

如果您想 grep 包含 "f" 但不包含 "gf" 的所有行,您可以

v1 <- c("abc", "f", "gf" )
grep( "(?<![g])f" , v1, perl= TRUE )
[1] 2

如果你只想grep那些包含"f"但不包含"fg"的人

v2 <- c("abc", "f", "fg")
grep( "f(?![g])" , v2, perl= TRUE )
[1] 2

当然你也可以混合使用:

v3 <- c("abc", "f", "fg", "gf")
grep( "(?<![g])f(?![g])" , v3, perl= TRUE )
[1] 2

所以对于你的情况,你可以这样做

df[ grep( "(?<![g])f" , df$V1, perl= TRUE ), "V5" ] <- 111
df[ grep( "gf" , df$V1, perl= TRUE ), "V5" ] <- 222

【讨论】:

    【解决方案2】:
     df$V5 <- NA
     df$V5[grep("f", df$V1)] <- 111
     df$V5[grep("gf", df$V1)] <- 222  # obviously some of the "f" values could be overwritten.
    

    有一个 switch 函数,我太密集了以至于无法理解,在我看来它应该像 Pascal case。我可以通过一些奇怪的布尔到数字索引操作来做到这一点,但这可能没有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-25
      • 1970-01-01
      • 2012-05-23
      • 2020-09-19
      • 2016-01-08
      • 2021-10-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多