2016-07-30 28 views
2

Ich habe ein Datenframe, in dem eine Spalte numerische Vektoren enthält. Ich möchte Zeilen basierend auf einer Bedingung filtern, die diese Spalte betrifft. Dies ist ein vereinfachtes Beispiel.R dplyr. Filtern Sie ein Datenframe, das eine Spalte mit numerischen Vektoren enthält

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 

Ich kann etwas wie Mapply verwenden, z.B.

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

die korrekt TRUE für die zweite Reihe zurückgibt, und FALSE für die Zeilen 1 und 2.

Allerdings habe ich Gründe, warum Ich mag würde dplyr Filter statt mapply verwenden, aber ich kann‘ t Get dplyr-Filter, um in der Spalte numvecs korrekt zu funktionieren. Anstatt zwei Zeilen zurückzugeben, gibt der folgende keine Zeilen zurück.

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

Was bin ich hier? Wie kann ich einen bedingten Ausdruck filtern, der die Spalte numvecs enthält?

Und im Idealfall möchte ich auch das nicht standardmäßige Bewertungsfilter_ verwenden, damit ich die Filterbedingung als Argument übergeben kann. Jede Hilfe wird geschätzt. Vielen Dank.

+0

Sie können die 'map' von' Bibliothek überprüfen (purrr) ' – akrun

+0

df <- data.frame (id = LETTERS [1: 3], name = c ("Alice", "Bob", "Carol")) mylist = Liste (c (1,2,3), c (4,5), c (1,3,4)) df $ numvecs <- mylist df – JimBoy

+0

FYI dplyr kann mit data.frames arbeiten wie es ist, aber wenn es sich um große Daten handelt, lohnt es sich, sie in ein tbl_df umzuwandeln. – smci

Antwort

1

Sie können sapply auf der numvecs Spalte verwenden und einen Logikvektor für subsetting erstellen:

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

Danke, das ist hilfreich. Ich fand, dass ich NSE auch verwenden kann, d. H. – Garry

1

Wir haben noch mapply mit filter

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

Oder map von purrr verwenden können

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

Oder wir können dies auch in der Kette

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

Dank akrun. Ähnlich wie Psidom funktioniert auch mit NSE. Ich fand filter_ (df, "sapply (numvecs, Funktion (vec) 4% in% vec") funktioniert auch so Problem gelöst – Garry

+0

@Garry Ich aktualisierte mit einer 'map' Option. – akrun

+0

Eine weitere Option mit' purrr': 'Filter (df, map_lgl (numvecs, function (x) any (4% in% x)) ' – Sumedh