2012-05-03 30 views
21

szukam szybki sposób dostać się tam iz powrotem pomiędzy listą następującym formacie:Nazwany List do/z Data.Frame

$`a` 
    [1] 1 2 3 
$`b` 
    [1] 4 5 6 

do/z data.frame w następującym formacie :

name x 
1 a 1 
2 a 2 
3 a 3 
4 b 4 
5 b 5 
6 b 6 

(tak naprawdę nie obchodzi, co nazwy kolumn są w tym przypadku).

Oto ramka danych stosowane powyżej w formacie R:

df <- data.frame(name=c(rep("a",3),rep("b",3)), x=c(1:3,4:6)) 

Ponownie szukam dwóch oddzielnych operacji: jednej do zamiany powyższego data.frame na listę, a drugiego do konwersji z powrotem do data.frame.

Odpowiedz

26

Zastosowanie stack i unstack bazy R:

x <- data.frame(a=1:3, b=4:6) 

x 
    a b 
1 1 4 
2 2 5 
3 3 6 

Zastosowanie stack się od szerokości do wysokości, to znaczy stos wektory jedna na drugiej.

y <- stack(x) 
y 
    values ind 
1  1 a 
2  2 a 
3  3 a 
4  4 b 
5  5 b 
6  6 b 

Użyj odwrotnej kolejności, aby uzyskać unstack.

unstack(y) 
    a b 
1 1 4 
2 2 5 
3 3 6 

Jeśli struktura danych jest bardziej skomplikowana, niż opisane, stack i unstack może już nie być odpowiednie. W takim przypadku będziesz musiał użyć reshape w bazie R lub melt i dcast w pakiecie reshape2.

7

Może coś takiego:

X <- split(df$x, df$name) 
data.frame(name = rep(names(X), sapply(X, length)), 
    x=do.call('c', X)) 

EDIT:postanowiłem połączyć Andrie a ja za rozwiązanie w jedną, która wydaje się być dokładnie tym, co PO poprosił o dość prosta. Z tego powodu nie rozumiem sytuacji, w której dane byłyby przetwarzane w ten sposób, a nie jak Andrie to robiła, ponieważ ramka danych jest w każdym razie listą wektorów o jednakowej długości.

# Your data set 
df <- data.frame(name=c(rep("a",3),rep("b",3)), x=c(1:3,4:6)) 

# converting it to list of vectors 
X <- split(df[, 2], df[, 1]) 
# converting it to a dataframe 
Y <- stack(X)[, 2:1]; names(Y) <- names(df) 

# Take Y and feed it back to these lines to show it 
# switches back and forth 
(X <- split(Y[, 2], Y[, 1])) 
Y <- stack(X)[, 2:1]; names(Y) <- names(df);Y 
+0

+1 Myślałem, że może "stopić (as.data.frame (...), value.name = 'x', variable.name = 'name')', aby powrócić do ramki danych. – joran

+0

Należy zauważyć, że podział powoduje zmianę kolejności ramek danych, ponieważ buduje współczynnik drugiego wektora. Zobacz także [Tworzenie nazwanej listy z dwóch wektorów (nazwy, wartości)] (http://stackoverflow.com/questions/17842705/creating-a-named-list-from-twoja-uektory-nazwa-wartości) dla rozwiązania używając 'mapply'. – jnas

2

życzę, aby z nadzieją nietrywialne uwagę, że @Tyler Rinker jest sugestia

X <- split(df$x, df$name) 

można zrobić bardziej ogólnie z

X <- split(df, df$name) 

Podział @Tyler Rinker za() Wyjaśnienie pasuje do książki kucharskiej R

http://my.safaribooksonline.com/book/programming/r/9780596809287/6dot1dot-splitting-a-vector-into-groups/id3392005

specifyin g, że wektor można pogrupować, podczas gdy w rzeczywistości można pogrupować całą ramkę danych. Sądzę, że grupowanie ramek danych, a nie wektora, byłoby bardziej wartościowym narzędziem (a właściwie to, co doprowadziło mnie do tego stanowiska).

(df <- data.frame(name=c(rep("a",3),rep("b",3), rep("c",3)), x=c(1:3,4:6, 7:9))) 
(X <- split(df, df$name)) 

HTH.