列表中的某些项目

时间:2017-12-12 06:10:40

标签: r

我有这个清单

Mylist <- c("orange", "apple", "cherry")

这个数据框

df<- data.frame(id = c(1,2,3), value = c("orange, peach, apple", "pineapple, mandarine, coconut", "cherry, peach"))

我希望选择 value 包含列表中一定数量元素的行。

在这个例子中,我希望看到至少有0个元素的行(至少1个)。 但是,0可以是变量。

所以,我理想的输出是

id             value
1          orange, peach, apple
3                 cherry, peach

我试过了,但它没有给我正确的结果。

df[sapply(strsplit(as.character(df$value), ","), function(x)  
  (x %in% Mylist)) > 0,]; 

如果有人建议我上面的代码出了什么问题我很感激。

2 个答案:

答案 0 :(得分:2)

我们可以pattern paste创建'{1}}'Mylist'的元素,并使用'grep'检查它是否存在于'value'列中,并基于该<对数据集对象进行子集化< / p>

df[grepl(paste0("\\b(", paste(tolower(Mylist), collapse="|"), ")\\b"), tolower(df$value)),]
#  id                value
#1  1 orange, peach, apple
#3  3        cherry, peach

如果我们根据计数需要它,那么

library(stringr)
df[Reduce(`+`, lapply(Mylist, str_count, string = df$value)) > 1,]
#  id                value
#1  1 orange, peach, apple

答案 1 :(得分:1)

你遇到的一个问题是,如果你检查:strsplit(as.character(df$value), ",")[[1]],你会看到它返回# [1] "orange" " peach" " apple"注意桃子和苹果前的空格。在不更改代码的情况下,快速解决方法是在", "上进行拆分。

第二个问题是你的df中有"Cherry",但列表中有"cherry"。 %in%只会检测精确的字符串匹配。如果有大小写差异的原因,您可以使用tolower()之类的函数。

第三是sapply(strsplit(as.character(df$value), ", "), function(x) (x %in% Mylist))返回一个bool列表,因此>无法解释它(这是错误信息应该告诉你的内容)所以你可以改为{{1使用对代码的最少更改来解决您的问题。

说过最好退后一步,创建一个返回匹配项计数的函数,并将该函数传递给lappy或sapply。