在dplyr中的字符串列上过滤多个值

Tom*_*m O 63 r string-matching multiple-conditions dplyr

data.frame在其中一列中有一个字符数据.我想data.frame在同一列中过滤多个选项.有没有一种简单的方法可以做到这一点,我错过了?

示例: data.frame name =dat

days      name
88        Lynn
11          Tom
2           Chris
5           Lisa
22        Kyla
1          Tom
222      Lynn
2         Lynn
Run Code Online (Sandbox Code Playgroud)

我想过滤一下Tom,Lynn例如.
当我做:

target <- c("Tom", "Lynn")
filt <- filter(dat, name == target)
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

longer object length is not a multiple of shorter object length
Run Code Online (Sandbox Code Playgroud)

Bro*_*ieG 174

你需要%in%而不是==:

library(dplyr)
target <- c("Tom", "Lynn")
filter(dat, name %in% target)  # equivalently, dat %>% filter(name %in% target)
Run Code Online (Sandbox Code Playgroud)

产生

  days name
1   88 Lynn
2   11  Tom
3    1  Tom
4  222 Lynn
5    2 Lynn
Run Code Online (Sandbox Code Playgroud)

要了解原因,请考虑这里发生的事情:

dat$name == target
# [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
Run Code Online (Sandbox Code Playgroud)

基本上,我们将两个长度target向量回收四次以匹配长度dat$name.换句话说,我们正在做:

 Lynn == Tom
  Tom == Lynn
Chris == Tom
 Lisa == Lynn
 ... continue repeating Tom and Lynn until end of data frame
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们不会收到错误,因为我怀疑您的数据框实际上有不同数量的行不允许回收,但您提供的示例(8行).如果样本有一个奇数行,我会得到与你相同的错误.但即使回收工作,这显然不是你想要的.基本上,该陈述dat$name == target相当于说:

返回TRUE等于"Tom"的每个奇数值或等于"Lynn"的每个偶数值.

碰巧的是,样本数据框中的最后一个值是偶数并且等于"Lynn",因此TRUE上面的那个值.

相比之下,dat$name %in% target说:

对于每个值dat$name,检查它是否存在于target.

非常不一样.结果如下:

[1]  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE
Run Code Online (Sandbox Code Playgroud)

注意你的问题与之无关dplyr,只是误用了==.

  • 不能使用 `%in%`,但您可以执行 `grepl("T[oi]m|lynne?", name)` 并使用您想要的任何模式。 (2认同)

mpa*_*nco 9

使用base包:

df <- data.frame(days = c(88, 11, 2, 5, 22, 1, 222, 2), name = c("Lynn", "Tom", "Chris", "Lisa", "Kyla", "Tom", "Lynn", "Lynn"))

# Three lines
target <- c("Tom", "Lynn")
index <- df$name %in% target
df[index, ]

# One line
df[df$name %in% c("Tom", "Lynn"), ] 
Run Code Online (Sandbox Code Playgroud)

输出:

  days name
1   88 Lynn
2   11  Tom
6    1  Tom
7  222 Lynn
8    2 Lynn
Run Code Online (Sandbox Code Playgroud)

使用sqldf:

library(sqldf)
# Two alternatives:
sqldf('SELECT *
      FROM df 
      WHERE name = "Tom" OR name = "Lynn"')
sqldf('SELECT *
      FROM df 
      WHERE name IN ("Tom", "Lynn")')
Run Code Online (Sandbox Code Playgroud)


Aut*_*erd 9

这可以使用dplyr软件包实现,该软件包可在CRAN中使用.实现这个目标的简单方法:

  1. 安装dplyr包.

  2. library(dplyr) df<- select(filter(dat,name=='tom'| name=='Lynn',c('days','name))

说明:

因此,一旦我们下载了dplyr,我们就可以使用此包中的两个不同函数创建一个新的数据框:

filter:第一个参数是数据帧; 第二个参数是我们希望它被子集化的条件.结果是整个数据框只有我们想要的行.select:第一个参数是数据框; 第二个参数是我们想要从中选择的列的名称.我们不必使用names()函数,甚至不必使用引号.我们只是将列名列为对象.