2017-07-17 4 views
6

私はcbindまたはunnestまたはas.data.table部分的にネストされたリストを試しています。 IDの部分的にネストされたリストを持つ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) 

lengthはABAB(この場合は2)と同じです。私はどのように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と仮定していますこのケースを一般的な方法で解決するソリューションがほしいと思っています。 – CPak

+0

@ChiPak同じリストを2回(AB、AB)含むABABを使用してサンプルデータを簡単に作成しました。私の実際の人生の例は、さまざまなリストを含んでいます( 'ABAB < - list(AB、CD)') –

答えて

5

を:

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 

lapplyunlistrecursive=FALSEで抽出した二つの要素(AとB変数をそれぞれ含む)のリストを取ります。これはリサイクルによってB変数が埋められた文字行列のリストを返します。 as.list(nested_list[[1]])からの個々のid変数のリストと行列の照らしは、Mapに送られ、対応するペアをdata.frameに変換し、列に希望の名前を与え、data.framesのリストを返します。最後に、このdata.framesのリストはReduceに送られ、結果は単一のdata.frameにrbindです。

最終的な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

そして1以上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

:私はより一般的なケースのためにテストしていませんが、これはOP例のために働く

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 
関連する問題