Reputation: 1728
Suppose this is my list structure
lst=list(structure(c("level1", "level2", "level4", "level5","18", "abc", "pqr", "lmn"),
.Dim = c(4L, 2L)),
structure(c("level1", "level2", "level3", "level5", "level6", "20", "xyz", "hive", "foo", "bar"),
.Dim = c(5L, 2L)),
structure(c("level1", "level3", "level4", "level5","level6", "22", "dark", "yellow","foobar", "blue"),
.Dim = c(5L, 2L)),
structure(c("level1", "level2", "level3", "level5","level6","level7","24", "dvd", "dxs","glass", "while","though"),
.Dim = c(6L, 2L))
)
Expecting O/P something like this
level1 level2 level3 level4 level5 level6 level7
1) 18 abc NA pqr lmn NA NA
2) 20 xyz hive NA foo bar NA
3) 22 NA dark yellow foobar blue NA
4) 24 dvd dxs NA glass while though
The first column from all list should be transposed and accordingly, corresponding data should get looked up to their rows.
Trying to do transpose of all rows to column itself giving error
unique(t(list_temp[[c(1,2)]][,1]))
ERROR:Error in list_temp[[c(1, 2)]][, 1] : incorrect number of dimensions
Also tried with
apply(list_temp,1,function(x){list_temp[[x]][,1]})
But gave me
Error in apply(list_temp, 1, function(x) { :
dim(X) must have a positive length
Any suggestion on how should it be done.
Thanks.
Upvotes: 3
Views: 2051
Reputation: 83215
Two approaches:
1) using the data.table-package
With:
library(data.table)
dcast(rbindlist(lapply(lst, as.data.table), idcol = 'id'),
id ~ V1, value.var = 'V2')[, id := NULL][]
you get:
level1 level2 level3 level4 level5 level6 level7 1: 18 abc NA pqr lmn NA NA 2: 20 xyz hive NA foo bar NA 3: 22 NA dark yellow foobar blue NA 4: 24 dvd dxs NA glass while though
2) using base R
With:
reshape(transform(do.call(rbind.data.frame, lst),
r = rep(seq_along(lst), lengths(lst)/2)),
idvar = 'r', timevar = 'V1', direction = 'wide')[,-1]
you get:
V2.level1 V2.level2 V2.level4 V2.level5 V2.level3 V2.level6 V2.level7 1 18 abc pqr lmn <NA> <NA> <NA> 5 20 xyz <NA> foo hive bar <NA> 10 22 <NA> yellow foobar dark blue <NA> 15 24 dvd <NA> glass dxs while though
Upvotes: 5
Reputation: 51582
Here is another idea using Reduce
to merge the data frames, then transpose and do some cleaning, i.e.
m1 <- t(Reduce(function(...) merge(..., by = 'V1', all = TRUE), lapply(lst, as.data.frame)))
colnames(m1) <- m1[1,]
row.names(m1) <- NULL
final_d <- as.data.frame(m1[-1,], stringsAsFactors = FALSE)
which gives,
level1 level2 level4 level5 level3 level6 level7 1 18 abc pqr lmn <NA> <NA> <NA> 2 20 xyz <NA> foo hive bar <NA> 3 22 <NA> yellow foobar dark blue <NA> 4 24 dvd <NA> glass dxs while though
Upvotes: 2