2015-04-29 1 views
1

Предположим, что у меня есть неопределенное число векторов разной длины, и я хочу эффективно объединить их вместе с предостережением, что каждый из них должен занимать другой столбец в результирующий data.frame. Вы можете предположить, что векторы содержатся в списке, но вы не можете зависеть от каких-либо имен компонентов, которые могут быть определены в списке.Как перевести векторы в разные столбцы, оставив NA в оставшихся ячейках

Ниже я представляю случайный образец ввода (lv) и плохое решение для создания требуемого вывода, которое вручную создает результирующий файл данных путем повторения NA и объединения каждого входного вектора по имени.

set.seed(1); 
lv <- list(a=sample(30,5),b=sample(30,3),c=sample(30,7),d=sample(30,2)); 
lv; 
## $a 
## [1] 8 11 17 25 6 
## 
## $b 
## [1] 27 28 19 
## 
## $c 
## [1] 19 2 6 5 18 10 30 
## 
## $d 
## [1] 15 21 
## 
with(lv,data.frame(a=c(a,rep(NA,length(b)+length(c)+length(d))),b=c(rep(NA,length(a)),b,rep(NA,length(c)+length(d))),c=c(rep(NA,length(a)+length(b)),c,rep(NA,length(d))),d=c(rep(NA,length(a)+length(b)+length(c)),d))); 
##  a b c d 
## 1 8 NA NA NA 
## 2 11 NA NA NA 
## 3 17 NA NA NA 
## 4 25 NA NA NA 
## 5 6 NA NA NA 
## 6 NA 27 NA NA 
## 7 NA 28 NA NA 
## 8 NA 19 NA NA 
## 9 NA NA 19 NA 
## 10 NA NA 2 NA 
## 11 NA NA 6 NA 
## 12 NA NA 5 NA 
## 13 NA NA 18 NA 
## 14 NA NA 10 NA 
## 15 NA NA 30 NA 
## 16 NA NA NA 15 
## 17 NA NA NA 21 

Примечание: Вы не должны использовать rbind(), я просто чувствовал, что это был самый ясный способ представить эту проблему. Другой способ задуматься об этом - это то, что я хочу, чтобы векторы были в разные (никогда перекрывающиеся) строки.

+2

Используйте 'set.seed' при представлении случайной выборки, поэтому мы сможем ее воспроизвести. –

+0

Может ли любое из значений быть 0? – joran

+0

@joran, да, они могут быть равны нулю. – bgoldst

ответ

4

Попробуйте

library(reshape2) 
library(data.table) 
dcast(setDT(melt(lv))[, rn:=.I], rn~L1, value.var='value') 

Или

dcast(setDT(melt(lv), keep.rownames=TRUE), 
        as.numeric(rn)~L1, value.var='value') 

Или как это было предложено @David Arenburg

recast(lv, seq_along(unlist(lv)) ~ L1) 

Или с помощью base R

d1 <- stack(lv) 
reshape(transform(d1, rn=1:nrow(d1)), idvar='rn', 
         timevar='ind', direction='wide') 
+0

@dayne Спасибо, я пытался избежать 'reshape2', кажется, что мне это нужно. – akrun

+1

Вам не нужно 'reshape2' в dev-версии. Вместо этого вы можете сделать 'rn: = .I'. Наконец, я понятия не имею, как это было так быстро. –

+0

Ты мастер, @akrun, это было быстро! Можно ли сделать это в базе R? – bgoldst

Смежные вопросы