2014-07-24 14 views
18

Hinzufügen von I mit einem Punkt getrennten Zeichenspalt einen Datenrahmen aufweisen:mehr Spalten in einer dplyr mutieren nennen

> set.seed(310366) 
> tst = data.frame(x=1:10,y=paste(sample(c("FOO","BAR","BAZ"),10,TRUE),".",sample(c("foo","bar","baz"),10,TRUE),sep="")) 
> tst 
    x  y 
1 1 BAR.baz 
2 2 FOO.foo 
3 3 BAZ.baz 
4 4 BAZ.foo 
5 5 BAZ.bar 
6 6 FOO.baz 
7 7 BAR.bar 
8 8 BAZ.baz 

und ich möchte aufzuspalten diese Spalte in zwei neue Spalten, die Teile zu beiden Seiten der Aufnahme Punkt. str_split_fixed aus Paket stringr kann die Arbeit ganz nett erledigen. Alle meine Werte sind auf jeden Fall zwei durch einen Punkt getrennt Teile, so kann ich tun:

> require(stringr) 
> str_split_fixed(tst$y,"\\.",2) 
     [,1] [,2] 
[1,] "BAR" "baz" 
[2,] "FOO" "foo" 
[3,] "BAZ" "baz" 
[4,] "BAZ" "foo" 
[5,] "BAZ" "bar" 
[6,] "FOO" "baz" 
[7,] "BAR" "bar" 

Jetzt konnte ich nur cbind, dass meine Daten Rahmen, aber ich dachte, ich würde herausfinden, wie das zu tun, in einer dplyr Pipeline. Zuerst dachte ich, mutate es in ein tun könnte:

> tst %.% mutate(parts=str_split_fixed(y,"\\.",2)) 
Error: wrong result size (20), expected 10 or 1 

Ich kann mutate bekommen es in zwei zu tun:

> tst %.% mutate(part1=str_split_fixed(y,"\\.",2)[,1], part2=str_split_fixed(y,"\\.",2)[,2]) 
    x  y part1 part2 
1 1 BAR.baz BAR baz 
2 2 FOO.foo FOO foo 
3 3 BAZ.baz BAZ baz 
4 4 BAZ.foo BAZ foo 
5 5 BAZ.bar BAZ bar 
6 6 FOO.baz FOO baz 

aber das ist zweimal die Zeichenfolge Split läuft.

„Best“ Ich kann tun, so weit in eine dplyr Weise ist dies (was ich nur entdeckt, während diese Frage zu schreiben ...):

> tst %.% do(cbind(.,data.frame(parts=str_split_fixed(.$y,"\\.",2)))) 
    x  y parts.1 parts.2 
1 1 BAR.baz  BAR  baz 
2 2 FOO.foo  FOO  foo 
3 3 BAZ.baz  BAZ  baz 
4 4 BAZ.foo  BAZ  foo 
5 5 BAZ.bar  BAZ  bar 

die nicht schlecht ist, aber verliert viel die Lesbarkeit von piped Dinge in R. Gibt es einen einfachen Ansatz mit mutate, die ich verpasst habe?

Antwort

36

Sie können separate() von tidyr in Kombination mit dplyr verwenden:

tst %>% separate(y, c("y1", "y2"), sep = "\\.", remove=FALSE) 

    x  y y1 y2 
1 1 BAR.baz BAR baz 
2 2 FOO.foo FOO foo 
3 3 BAZ.baz BAZ baz 
4 4 BAZ.foo BAZ foo 
5 5 BAZ.bar BAZ bar 
6 6 FOO.baz FOO baz 
7 7 BAR.bar BAR bar 
8 8 BAZ.baz BAZ baz 
9 9 FOO.bar FOO bar 
10 10 BAR.foo BAR foo 

Einstellung remove=TRUE Spalte y ungefähr so ​​einfach

+1

Looks entfernen wird, wie es erhält. Ein weiterer Grund für ein Upgrade auf 3.1 ... – Spacedman

+1

Leider gibt 'separate' einen Fehler, wenn das Ergebnis nach dem Spalten mehr Spalten als spezifiziert hat. In diesem Sinne funktioniert es eher wie "str_split" als "str_split_fixed". Siehe [diese Funktion anfordern] (https://github.com/hadley/tidyr/issues/19). Aber immer noch eine sehr hilfreiche Antwort, danke. – Beasterfield

+0

mit 'extra =" merge "' Parameter kann dies gesteuert werden –

Verwandte Themen