【问题标题】:Filtering observations by using grep the reverse way in R在 R 中使用 grep 以相反的方式过滤观察结果
【发布时间】:2016-03-18 18:04:18
【问题描述】:

如下图:

    df <- data.frame(X1 = rep(letters[1:3],3),
                     X2 = 1:9,
                     X3 = sample(1:50,9))
    df
    ind<- grep("a|c", df$X1)
    library(data.table)
    df_ac <- df[ind,]
    df_b <- df[!ind,]

df_ac 是使用常规的grep 命令创建的。如果我想以相反的方式使用grep:使用X1 == 'b' 选择所有观察值。 我知道我可以这样做:

ind2<- grep("a|c", df$X1, invert = T)
df_b <-df[ind2,]

但是,在我的原始脚本中,为什么命令 df_b &lt;-df[!ind,] 返回一个观察值为零的数据框? 任何人都可以向我解释为什么我的逻辑是错误的?有没有其他方法可以通过反向使用grep 而不指定invert = T 来选择data.frame 中的观察值?谢谢!

【问题讨论】:

  • 您确定要使用grep 而不是%in%?此外,如果您想要 grep 方法,您可能想查看 grepl
  • 另外,你为什么在这里加载“data.table”?
  • 在您的控制台中执行!ind,您将看到为什么该表达式返回一个空的data.frame
  • 嗨,我使用“data.table”,因为我的原始数据集很大,我想使用 data.table 来操作我的数据集。我稍微编辑了我的问题。我只想知道为什么我在data.table 中的逻辑不正确。谢谢
  • @nrussell 让我很惊讶,FALSE !ind。我意识到grep 返回数字索引,但!ind 是一个逻辑运算符,它永远不会给我想要的东西。我需要改用grepl。非常感谢您的提示!

标签: r data.table


【解决方案1】:

您可能对greplgrep 更感兴趣:

ind<- grepl("a|c", df$X1)
df[ind,]
#   X1 X2 X3
# 1  a  1 16
# 3  c  3 38
# 4  a  4 10
# 6  c  6 18
# 7  a  7 33
# 9  c  9 49

df[!ind,]
#   X1 X2 X3
# 2  b  2  5
# 5  b  5 14
# 8  b  8 50

或者,继续使用“data.table”并尝试%in% 看看还有什么可能对您有用。注意语法的不同。

ind2 <- c("a", "c")
library(data.table)
setDT(df)
df[X1 %in% ind2]
#    X1 X2 X3
# 1:  a  1 16
# 2:  c  3 38
# 3:  a  4 10
# 4:  c  6 18
# 5:  a  7 33
# 6:  c  9 49

df[!X1 %in% ind2]
#    X1 X2 X3
# 1:  b  2  5
# 2:  b  5 14
# 3:  b  8 50

【讨论】:

  • 非常感谢!它适用于grepldata.table 似乎喜欢使用逻辑模式而不是使用数字索引来识别观察结果。我会投票给你的答案。
  • @ChuanTang,你总是可以做到df[setdiff(seq_len(nrow(df)), ind)]。但这比仅仅使用grepl要麻烦得多。
  • @ChuanTang 在这种情况下,逻辑索引有好处,因为%in% 有一些优化。此外,%chin% 通常比 %in% 更推荐用于字符向量(出于某种原因......)。
猜你喜欢
  • 2014-10-17
  • 2014-11-17
  • 2017-07-01
  • 2020-09-27
  • 2018-06-12
  • 1970-01-01
  • 2017-10-09
  • 1970-01-01
  • 2018-11-28
相关资源
最近更新 更多