2016-07-30 102 views
2

我有一个数据帧,其中一列包含数字向量。我想根据涉及该列的条件过滤行。这是一个简单的例子。R dplyr。过滤包含一列数字向量的数据帧

df <- data.frame(id = LETTERS[1:3], name=c("Alice", "Bob", "Carol")) 
mylist=list(c(1,2,3), c(4,5), c(1,3,4)) 
df$numvecs <- mylist 
df 
# id name numvecs 
# 1 A Alice 1, 2, 3 
# 2 B Bob 4, 5 
# 3 C Carol 1, 3, 4 

我可以使用像mapply,

mapply(function(x,y) x=="B" & 4 %in% y, df$id, df$numvecs) 

其正确第二行返回TRUE,而假的行1和2

不过,我有原因,我想使用dplyr过滤器,而不是mapply,但我可以”让dplyr过滤器在numvecs列上正常运行。而不是返回两行,以下内容不返回任何行。

filter(df, 4 %in% numvecs) 
# [1] id  numvecs 
# <0 rows> (or 0-length row.names) 

我在这里错过了什么?如何过滤涉及numvecs列的条件表达式?

理想情况下,我也想使用非标准评估filter_,所以我可以将过滤条件作为参数传递。任何帮助赞赏。谢谢。

+0

可以检查从'库中的'map'(purrr)' – akrun

+0

DF < - data.frame(ID = LETTERS [1:3], name = c(“Alice”,“Bob”,“Carol”)) mylist = list(c(1,2,3),c(4,5),c(1,3,4)) df $ numvecs < - mylist df – JimBoy

+0

FYI dplyr可以按原样处理data.frames,但如果您处理的是大数据,则将其转换为tbl_df值得。 – smci

回答

1

您可以在numvecs列中使用sapply并创建子集逻辑矢量:

library(dplyr) 
filter(df, sapply(numvecs, function(vec) 4 %in% vec), id == "B") 
# id name numvecs 
# 1 B Bob 4, 5 

filter(df, sapply(numvecs, function(vec) 4 %in% vec)) 
# id name numvecs 
# 1 B Bob 4, 5 
# 2 C Carol 1, 3, 4 
+0

谢谢,这很有帮助。我发现我也可以使用NSE,即 – Garry

1

我们仍然可以使用mapplyfilter

filter(df, mapply(function(x,y) x == "B" & 4 %in% y, id, numvecs)) 
# id name numvecs 
#1 B Bob 4, 5 

或者使用mappurrr

library(purrr) 
filter(df, unlist(map(numvecs, ~4 %in% .x))) 
# id name numvecs 
#1 B Bob 4, 5 
#2 C Carol 1, 3, 4 

或者还可以做到这一点在链

df %>% 
    .$numvecs %>% 
    map(~ 4 %in% .x) %>% 
    unlist %>% 
    df[.,] 
# id name numvecs 
#2 B Bob 4, 5 
#3 C Carol 1, 3, 4 
+1

谢谢akrun。与Psidom类似,也适用于NSE。我发现filter_(df,“sapply(numvecs,函数(vec)%%vec”)也可以解决问题 – Garry

+0

@Garry我用'map'选项更新了 – akrun

+0

另一个使用'purrr'的选项:'filter (df,map_lgl(numvecs,function(x)any(4%in%x)))' – Sumedh