2017-07-17 52 views
6

我试图cbindunnestas.data.table一个部分嵌套列表。cbind与部分嵌套列表

id <- c(1,2) 
A <- c("A1","A2","A3") 
B <- c("B1") 
AB <- list(A=A,B=B) 
ABAB <- list(AB,AB) 
nested_list <- list(id=id,ABAB=ABAB) 

id为length相同(在此情况2)ABAB。我不知道如何unlist这个列表(ABAB)的一部分和cbind另一部分(id)。这是我想要的结果作为data.table

data.table(id=c(1,1,1,2,2,2),A=c("A1","A2","A3","A1","A2","A3"),B=rep("B1",6)) 
    id A B 
1: 1 A1 B1 
2: 1 A2 B1 
3: 1 A3 B1 
4: 2 A1 B1 
5: 2 A2 B1 
6: 2 A3 B1 
+0

我假设y ou想要一个解决方案,以一般的方式解决这个案例... – CPak

+0

@ChiPak我用包含相同列表两次(AB,AB)的ABAB的示例数据简化了它。我现实生活中的例子,包含不同的列表('ABAB < - list(AB,CD)') –

回答

5

我没有为更一般的情况进行测试,但该方法适用于OP例如:

library(data.table) 

as.data.table(nested_list)[, lapply(ABAB, as.data.table)[[1]], id] 
# id A B 
#1: 1 A1 B1 
#2: 1 A2 B1 
#3: 1 A3 B1 
#4: 2 A1 B1 
#5: 2 A2 B1 
#6: 2 A3 B1 

或者另一种选择(这可能是更快,但更详细):

rbindlist(lapply(nested_list$ABAB, as.data.table), 
      idcol = 'id')[, id := nested_list$id[id]] 
5

这是一些超级丑陋的基地R,但产生所需的输出。

Reduce(rbind, Map(function(x, y) setNames(data.frame(x, y), c("id", "A", "B")), 
        as.list(nested_list[[1]]), 
        lapply(unlist(nested_list[-1], recursive=FALSE), 
         function(x) Reduce(cbind, x)))) 
    id A B 
1 1 A1 B1 
2 1 A2 B1 
3 1 A3 B1 
4 2 A1 B1 
5 2 A2 B1 
6 2 A3 B1 

lapply需要两个元件(各自含有A和B的变量)与unlistrecursive=FALSE提取的列表。它返回一个字符矩阵列表,其中B变量通过循环填充。来自as.list(nested_list[[1]])的各个id变量以及矩阵点亮的列表被馈送给Map,其将对应的对转换为data.frame,并给出列所需的名称并返回data.frames列表。最后,将这个data.frames列表提供给Reduce,其中rbind是单个data.frame的结果。

如果需要,最后的Reduce(rbind,可以用data.table s rbindlist代替。

3

这是另一个可怕的解决方案

max_length = max(unlist(lapply(nested_list, function(x) lapply(x, lengths)))) 
data.frame(id = do.call(c, lapply(nested_list$id, rep, max_length)), 
      do.call(rbind, lapply(nested_list$ABAB, function(x) 
       do.call(cbind, lapply(x, function(y) { 
        if(length(y) < max_length) { 
         rep(y, max_length) 
        } else { 
         y 
        } 
       }))))) 
# id A B 
#1 1 A1 B1 
#2 1 A2 B1 
#3 1 A3 B1 
#4 2 A1 B1 
#5 2 A2 B1 
#6 2 A3 B1 
2

还有一,也inelegant-但I`d由我看到其他的答案的时候走得太远了。

restructure <- function(nested_l) { 
    ids <- as.numeric(max(unlist(lapply(unlist(nested_l, recursive = FALSE), function(x){ 
    lapply(x, length) 
    })))) 

    temp = data.frame(rep(nested_l$id, each = ids), 
      sapply(1:length(nested_l$id), function(x){ 
       out <-unlist(lapply(nested_l[[2]], function(y){ 
       return(y[x]) 
       })) 
      })) 
    names(temp) <- c("id", unique(substring(unlist(nested_l[2]), first = 1, last = 1))) 
    return(temp) 
} 

> restructure(nested_list) 
    id A B 
1 1 A1 B1 
2 1 A2 B1 
3 1 A3 B1 
4 2 A1 B1 
5 2 A2 B1 
6 2 A3 B1 
1

参加此聚会:

library(tidyverse) 
temp <- map(nested_list,~map(.x,~expand.grid(.x))) 
df <- map_df(1:2,~cbind(temp$id[[.x]],temp$ABAB[[.x]])) 

    Var1 A B 
1 1 A1 B1 
2 1 A2 B1 
3 1 A3 B1 
4 2 A1 B1 
5 2 A2 B1 
6 2 A3 B1