2016-08-18 1 views
2

Ich habe einen data.frame wo eine der Variablen ist ein Vektor (oder eine Liste), wie folgt aus:strsplit auf einer Säule eines Datenrahmens

MyColumn <- c("A, B,C", "D,E", "F","G") 
MyDF <- data.frame(group_id=1:4, val=11:14, cat=MyColumn) 

# group_id val cat 
# 1  1 11 A, B,C 
# 2  2 12 D,E 
# 3  3 13  F 
# 4  4 14  G 

Ich möchte einen neuen Datenrahmen haben, mit so viele Zeilen wie der Vektor

FlatColumn <- unlist(strsplit(MyColumn,split=",")) 

, die wie folgt aussieht:

MyNewDF <- data.frame(group_id=c(rep(1,3),rep(2,2),3,4), val=c(rep(11,3),rep(12,2),13,14), cat=FlatColumn) 

# group_id val cat 
# 1  1 11 A 
# 2  1 11 B 
# 3  1 11 C 
# 4  2 12 D 
# 5  2 12 E 
# 6  3 13 F 
# 7  4 14 G 

im Wesentlichen für jeden Faktor, der ein Verput ist t der Liste von MyColumn (die Buchstaben A bis G), möchte ich die entsprechenden Werte der Liste zuweisen. Jeder Faktor erscheint nur einmal in MyColumn.

Gibt es einen guten Weg für diese Art der Umformung/Nichtlisting/Zusammenführung? Ich habe eine sehr umständliche for-Schleife über die Zeilen MyDFund die Länge des entsprechenden Elements von strsplit(MyColumn,split=","). Ich bin mir sicher, dass es einen eleganteren Weg geben muss.

Antwort

5

Wie wäre es

lst <- strsplit(MyColumn, split = ",") 
k <- lengths(lst) ## expansion size 
FlatColumn <- unlist(lst, use.names = FALSE) 
MyNewDF <- data.frame(group_id = rep.int(MyDF$group_id, k), 
         val = rep.int(MyDF$val, k), 
         cat = FlatColumn) 

# group_id val cat 
#1  1 11 A 
#2  1 11 B 
#3  1 11 C 
#4  2 12 D 
#5  2 12 E 
#6  3 13 F 
#7  4 14 G 
4

Sie können separate_rows von tidyr verwenden:

tidyr::separate_rows(MyDF, cat) 

# group_id val cat 
# 1  1 11 A 
# 2  1 11 B 
# 3  1 11 C 
# 4  2 12 D 
# 5  2 12 E 
# 6  3 13 F 
# 7  4 14 G 
3

Wir cSplit von splitstackshape

library(splitstackshape) 
cSplit(MyDF, "cat", ",", "long") 
# group_id val cat 
#1:  1 11 A 
#2:  1 11 B 
#3:  1 11 C 
#4:  2 12 D 
#5:  2 12 E 
#6:  3 13 F 
#7:  4 14 G 
können

Wir können auch base R mit strsplit verwenden, um die 'cat'-Spalte in eine list aufzuteilen, die Reihenfolgen von' MyDF 'mit der lengths von' lst 'zu replizieren und die' cat'-Spalte durch unlist zu erstellen. lst '.

lst <- strsplit(as.character(MyDF$cat), ",") 
transform(MyDF[rep(1:nrow(MyDF), lengths(lst)),-3], cat = unlist(lst)) 
Verwandte Themen