2015-04-23 8 views
9

Ich habe Probleme, eine Teilmenge von Zeilen in dplyr zu mutieren. Ich bin mit dem Verkettungs Befehl: %>% sagen:R So mutieren Sie eine Teilmenge von Zeilen

data <- data %>% 
    filter(ColA == "ABC") %>% 
    mutate(ColB = "XXXX") 

Dies funktioniert gut, aber die Probleme sind, dass ich möchte die gesamte Original-Tabelle auswählen können und sehen, die nur auf die Teilmenge von Daten angewandt mutieren Ich hatte angegeben. Mein Problem ist, dass, wenn ich Daten danach sehe ich nur die Teilmenge data und seine aktualisierte ColB Information sehe.

Ich würde auch gerne wissen, wie dies mit data.table zu tun.

Danke.

Antwort

9

Mit data.table, würden wir tun:

setDT(data)[colA == "ABC", ColB := "XXXX"] 

und die Werte werden geändert in-place, im Gegensatz zu if-else, which'd die gesamte Spalte kopieren ersetzen nur jene Zeilen, in denen die Bedingung erfüllt.

Wir nennen dies Sub-assign durch Bezugnahme. Sie können mehr darüber in der new HTML vignettes lesen.

+0

Vielen Dank. Das hat funktioniert. Und wie mache ich einen Filter für mehrere Kriterien? Ich versuchte folgendes, aber es scheint nicht die richtige Syntax zu sein. SetDT (Daten) [(colA == "ABC") & (colC == "DEF"), ColB: = "XXXX"] ' –

+0

@ user1991118 das * ist * die richtige Syntax - vielleicht können Sie ein reproduzierbares Beispiel zeigen. Das einzige, was mir einfällt, ist vielleicht, dass Sie '|' anstelle von '&' verwenden wollten. – eddi

+0

Das war in der Tat die richtige Syntax. Ich hatte die falsche Variable verwendet. Es funktioniert. –

4

Wenn Sie filter() verwenden, entfernen Sie tatsächlich die Zeilen, die nicht mit der angegebenen Bedingung übereinstimmen, sodass sie nicht im endgültigen Datensatz angezeigt werden.

Sind in Ihrem Datenrahmen bereits ColB vorhanden? Wenn ja,

data %>% 
    mutate(ColB = ifelse(ColA == "ABC", "XXXX", ColB)) 

ändert ColB-"XXXX" wenn ColA == "ABC" und lassen Sie es als sonst ist. Wenn ColB nicht bereits vorhanden ist, dann müssen Sie angeben, was für die Zeilen zu tun, wo ColA != "ABC", zum Beispiel:

data %>% 
    mutate(ColB = ifelse(ColA == "ABC", "XXXX", NA)) 
0

Eine weitere Möglichkeit ist es, eine nachfolgende Kombination von Union und anti-Join mit den gleichen Daten durchzuführen. Dies erfordert einen Primärschlüssel:

data <- data %>% 
    filter(ColA == "ABC") %>% 
    mutate(ColB = "XXXX") %>% 
    rbind_list(., anti_join(data, ., by = ...)) 

Beispiel:

mtcars_n <- mtcars %>% add_rownames 
mtcars_n %>% 
    filter(cyl > 6) %>% 
    mutate(mpg = 1) %>% 
    rbind_list(., anti_join(mtcars_n, ., by = "rowname")) 

Das ist viel langsamer als wahrscheinlich jeder anderer Ansatz, aber nützlich schnelle Ergebnisse zu erhalten, indem Sie Ihr bestehendes Rohr erstreckt.

Verwandte Themen