2016-07-30 163 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