2016-06-03 19 views
6

mam pewne dane jak poniżej:Kombajny listy z wektorem w R

num = list() 
num[[1]] = c(1,2,3) 
num[[2]] = c(4,5,6,7) 
name = c("Alex", "Patrick") 

Jak mogę połączyć go w ramce danych, które wygląda tak?

Alex  1 
Alex  2 
Alex  3 
Patrick  4 
Patrick  5 
Patrick  6 
Patrick  7 

Przykro mi z powodu zamieszczenia prawdopodobnie oczywistego pytania. Szukałem obszernie i nie znalazłem odpowiedzi, prawdopodobnie dlatego, że nie wiem jak dobrze opisać to zapytanie.

+3

'stack (setNames (num, nazwa))' – user20650

+0

@ user20650 dodać jako odpowiedź, nowa funkcja dnia - stos! – zx8754

+2

@ zx8754; ha, tak rzadko to pamiętam. .. ale myślę, że zostawiam to w komentarzach, ponieważ to naprawdę robi to, co robi odpowiedź Richarda S, ale z ubraniami. – user20650

Odpowiedz

8

Spróbuj. Przydaje się tutaj nowa funkcja lengths().

data.frame(name = rep(name, lengths(num)), num = unlist(num)) 
#  name num 
# 1 Alex 1 
# 2 Alex 2 
# 3 Alex 3 
# 4 Patrick 4 
# 5 Patrick 5 
# 6 Patrick 6 
# 7 Patrick 7 

Aby to zrozumieć trochę lepiej, podzielmy go na części od środka. lengths() mówi nam długości każdego elementu na liście, więc mamy

lengths(num) 
# [1] 3 4 

Teraz możemy użyć go jako times argument rep() replikować elementy name.

rep(name, lengths(num)) 
# [1] "Alex" "Alex" "Alex" "Patrick" "Patrick" "Patrick" "Patrick" 

To pierwsza kolumna. W przypadku drugiej kolumny przekształcamy num w wektor atomowy z unlist().

unlist(num) 
# [1] 1 2 3 4 5 6 7 

Umieść je razem, jak pokazano powyżej, a otrzymasz nową ramkę danych.

+0

To jest genialne. Trochę trudno śledzić funkcje zagnieżdżone, ale myślę, że rozumiem. Dzięki. –

+1

@AlexLach - Dodałem trochę wyjaśnienia. Mam nadzieję, że to pomoże –

3

Inna opcja:

data.table::rbindlist(Map(function(x,y) data.frame(name = x, num = y), name, num)) 
     name num 
1: Alex 1 
2: Alex 2 
3: Alex 3 
4: Patrick 4 
5: Patrick 5 
6: Patrick 6 
7: Patrick 7 
2

Albo możemy użyć stack po ustawieniu names z 'num' z 'name'

stack(setNames(num, name))[2:1] 
#  ind values 
#1 Alex  1 
#2 Alex  2 
#3 Alex  3 
#4 Patrick  4 
#5 Patrick  5 
#6 Patrick  6 
#7 Patrick  7 

Właśnie zauważyłem, że ten został opublikowany w komentarzach przez @ user20650 . W tym przypadku, możemy również zrobić

library(reshape2) 
melt(setNames(num, name))[2:1] 
#  L1 value 
#1 Alex  1 
#2 Alex  2 
#3 Alex  3 
#4 Patrick  4 
#5 Patrick  5 
#6 Patrick  6 
#7 Patrick  7