2017-07-17 11 views
6

मैं cbind या unnest या as.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) 

आईडी की length (इस मामले में 2) ABAB के समान है। मुझे नहीं पता कि unlist इस सूची का एक हिस्सा (एबीएबी) और cbind एक और भाग (आईडी) कैसे है। यहाँ एक 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 मैंने एबीएबी के साथ दो बार एक ही सूची (एबी, एबी) युक्त उदाहरण डेटा के साथ इसे सरल बना दिया। मेरा वास्तविक जीवन उदाहरण, अलग-अलग सूचियां ('ABAB <- सूची (एबी, सीडी)') –

उत्तर

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

यह कुछ सुपर बदसूरत आधार आर है, लेकिन वांछित आउटपुट पैदा करता है।

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 दो तत्वों (प्रत्येक ए और बी चर युक्त) unlist और recursive=FALSE साथ निकाली गई की एक सूची लेता है। यह रीसाइक्लिंग द्वारा भरे बी चर के साथ चरित्र matrices की एक सूची देता है। as.list(nested_list[[1]]) से अलग-अलग आईडी चरों की एक सूची और मैट्रिस की जलाई Map को खिलाया जाता है जो संबंधित जोड़ों को डेटा.फ्रेम में परिवर्तित करता है और स्तंभों को वांछित नाम देता है और डेटा.फ्रेम की एक सूची देता है। अंत में, data.frames की यह सूची Reduce पर खिलाई जाती है, जो rbind परिणामों को एक डेटा.फ्रेम पर परिणाम देती है।

अंतिम Reduce(rbind, को वांछित data.table एस 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- है, लेकिन मैं `घ बहुत दूर बार मैं अन्य उत्तर देखा से चला।

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 
संबंधित मुद्दे