2017-01-25 7 views
-1

Ich habe eine Liste:Filter ein Element einer Liste

name_lst <- list(one = c("John", "Paul", "Ringo", "Kramer"), 
       two = c("Jerry", "Kramer", "George", "Elaine")) 

Ich möchte „Kramer“ von name_lst[[SOME_VECTOR]], entfernen, aber den Rest der Liste zurückzukehren. Würde die Ausgabe gerne sein.

name_lst 
$one 
[1] "John" "Paul" "Ringo" 
$two 
[1] "Jerry" "Kramer" "George" "Elaine" 

Im Idealfall wäre ich die Lage, eine ganze Gruppe von Namen zu entfernen, nicht nur „Kramer“ (zB ! %in% c("George", "Kramer") Ich habe versucht:

name_lst[name_lst[1] != "Kramer"] 
name_lst[name_lst[[1]] != "Kramer"] 
name_lst[name_lst$one != "Kramer"] 
name_lst[!(name_lst$one %in% "Kramer")] 
name_lst[[name_lst[1] != "Kramer"]] 
name_lst[[name_lst[[1]] != "Kramer"]] 
name_lst[[name_lst$one != "Kramer"]] 
name_lst[[!(name_lst$one %in% "Kramer")]] 

Diese alle Rück Fehler oder die gleiche Liste ohne Änderungen

+0

Die Antwort ist gut für dieses spezielle Problem. Der allgemeine Ansatz für "tue etwas für jedes Element einer Liste" ist (1) schreibe eine Funktion, die es auch ein einzelnes Element tut, (2) 'lapply (your_function, your_list)'. – Gregor

+0

@Gregor Ich bin mir dessen bewusst. 'lapply' auf einer Liste ist gut dokumentiert mit Fragen und Antworten. Ich möchte das nur auf ein einzelnes Element anwenden, wie es der Titel impliziert. Ich habe meine Frage aktualisiert. – Tunn

+0

@Gregor, ich denke, du hast die Reihenfolge von 'your_function' und' your_list' durcheinander gebracht. Wenn Sie 'X =' und 'FUN =' nicht angeben, denke ich, dass 'your_list' zuerst sein muss? – rosscova

Antwort

4

Sie das Element festlegen, können Sie innerhalb aussehen wollen, dann filtern und zu diesem bestimmten Listenelement zuweisen.


Wenn, wie im Kommentar, Sie wollen nicht auf die Neuzuordnung durchzuführen, sondern um ein neues Objekt stattdessen erhalten möchten, purrr::map_if verwendet, ist ein Weg zu gehen.

library(purrr) 
NEW_NAME <- name_lst %>% 
    map_if(.p = names(.) == "two", ~ .[!(. %in% c("Kramer", "SomeoneElse"))]) 
# OR, without pipes: 
NEW_NAME <- map_if(name_lst, 
        names(name_lst) == "two", 
        ~ .x[!(.x %in% c("Kramer", "SomeoneElse"))]) 
+0

Schön, ich denke, das wird hilfreich für die Leute sein, da keine Websites, die ich gesehen habe, zeigen, wie es geht. Können Sie das auch auf einer Pipeline tun? Id.e., 'name_lst%>% FILTER_A_SPECIFIC_VECTOR%>% SOMETHING_ELSE'? Und können Sie es tun, ohne das Element am vorderen Ende von '<-' zu spezifizieren? D.h., NEW_NAME <- name_lst [FILTER_A_SPECIFIC_VECTOR] '? – Tunn

+1

Hier ist die Pipe-iest-Sache, die ich mir vorstellen konnte, und ich habe die Zuweisung am Backend mit '->': 'name_lst%>% \' [[\ '("zwei")%>% \ '[ \ '(!.% in% c ("Kramer", "SomeoneElse")) -> name_lst [["zwei"]]]. Ich weiß, das ist wahrscheinlich nicht das, was Sie meinten ... Ich bin mir nicht sicher, ob es eine gute Möglichkeit gibt, diesen Ansatz ohne die explizite Neuzuweisung oder Verwendung des globalen Zuweisungsoperators zu verwenden, aber anscheinend wollen Sie ein neues Objekt, keine Neuzuweisung.Du könntest jedoch 'purrr :: map_if' verwenden:' name_lst%>% purrr :: map_if (.p = namen (.) == "zwei", ~. [! (.% In% c ("Kramer" , "SomeoneElse"))]) '. – Jota

+0

Ja, das ist eine ausgefallene Untermenge! Die 'map_if' ist genau das, wonach ich gesucht habe, habe zu viel Zeit damit verbracht, herauszufinden, dass' list' (und 'data.frame') Subset-Syntax mit' map'-Funktionen ist. Wirf das in deine Antwort. – Tunn

0

Nicht viel zu @ Jota Antwort hinzufügen, nur eine andere Möglichkeit. Wenn Sie das/die zu bearbeitende Element/Elemente angeben möchten und die Möglichkeit haben, dies für mehrere Elemente zu tun, können Sie lapply verwenden, gelten jedoch nur für bestimmte Elemente.

Hinzufügen eines dritten Listenelements, nur damit wir an zwei Elementen statt an einem arbeiten können.

Stellen Sie die Parameter zuerst ein, weil ich denke, dass Code dazu neigt, auf diese Weise besser zu lesen.

names <- c("George", "Kramer") 
elements <- c(1, 3) 

Wenden Sie die names Filter auf die angegebenen elements der Liste.

library(magrittr) 

name_lst[ elements ] %<>% 
    lapply(function(x) x[!(x %in% names)]) 

Ausgang:

name_lst 
# $one 
# [1] "John" "Paul" "Ringo" 
# 
# $two 
# [1] "Jerry" "Kramer" "George" "Elaine" 
# 
# $three 
# [1] "John" "Paul" "Ringo" 
Verwandte Themen