2016-10-07 3 views
7

Ich habe eine data.frame wo einige Zellen Saiten Komma getrennte Werte enthalten:tidyr Verwendung separate_rows über mehrere Spalten

d <- data.frame(a=c(1:3), 
     b=c("name1, name2, name3", "name4", "name5, name6"), 
     c=c("name7","name8, name9", "name10")) 

Ich möchte diese Zeichenfolgen trennen, wo jeder Name in seine eigene Zelle aufgeteilt wird. Dies ist einfach mit

tidyr::separate_rows(d, b, sep=",") 

wenn es für eine Spalte einmal gemacht wird. Aber ich kann dies nicht für beide Spalten "b" und "c" gleichzeitig tun, da es erfordert, dass die Anzahl der Namen in jeder Zeichenfolge gleich ist. Anstatt zu schreiben

tidyr::separate_rows(d, b, sep=",") 
tidyr::separate_rows(d, c, sep=",") 

Gibt es eine Möglichkeit, dies in einem Einzeiler zu tun, z. mit anwenden? So etwas wie

apply(d, 2, separate_rows(...)) 

nicht sicher, wie die Argumente der separate_rows() Funktion zu übergeben.

Antwort

5

Sie können ein Rohr verwenden. Beachten Sie, dass sep = ", " automatisch erkannt wird.

d %>% separate_rows(b) %>% separate_rows(c) 
# a  b  c 
# 1 1 name1 name7 
# 2 1 name2 name7 
# 3 1 name3 name7 
# 4 2 name4 name8 
# 5 2 name4 name9 
# 6 3 name5 name10 
# 7 3 name6 name10 

Hinweis: Mit tidyr Version 0.6.0, wo der %>% Operator in dem Paket enthalten ist.


Update: Mit @doscendodiscimus Kommentar, könnten wir eine for() Schleife verwenden und neu zuzuweisen d in jeder Iteration. Auf diese Weise können wir so viele Spalten haben, wie wir möchten. Wir werden einen Zeichenvektor von Spaltennamen verwenden, daher müssen wir zur Standard-Testversion separate_rows_ wechseln.

cols <- c("b", "c") 
for(col in cols) { 
    d <- separate_rows_(d, col) 
} 

, die die aktualisierte d

a  b  c 
1 1 name1 name7 
2 1 name2 name7 
3 1 name3 name7 
4 2 name4 name8 
5 2 name4 name9 
6 3 name5 name10 
7 3 name6 name10 
+0

Nicht sicher, warum Sie nicht zwei Spalten gleichzeitig verwenden können. Das Argument in 'separate_rows_' wird' cols' genannt, was mich denken lässt, dass mehrere Spalten möglich sind, aber die Daten erlauben dies hier nicht. –

+1

Ja, ich könnte einfach die gleiche Zeile für jede Zeile schreiben, aber gibt es eine Möglichkeit, dies für n Spalten zu tun? Es wird mühsam, wenn Sie 10 oder mehr Spalten haben. Wenn Sie beide Spalten zur gleichen Zeit hinzufügen, wird ein Fehler angezeigt. – user23413

+3

@ user23413, könnten Sie versuchen, eine Schleife wie 'für (col in c (" b "," c ")) d <- separate_rows_ (d, col, sep =", ")' wenn Sie mit 'tidyr bleiben wollen ' –

4

Hier gibt es einen Alternativen Ansatz splitstackshape::cSplit und zoo::na.locf verwenden.

library(splitstackshape) 
library(zoo) 

df <- cSplit(d, 1:ncol(d), "long", sep = ",") 
na.locf(df[rowSums(is.na(df)) != ncol(df),]) 
# a  b  c 
#1: 1 name1 name7 
#2: 1 name2 name7 
#3: 1 name3 name7 
#4: 2 name4 name8 
#5: 2 name4 name9 
#6: 3 name5 name10 
#7: 3 name6 name10 
Verwandte Themen