2016-02-12 5 views
13

से लंबे प्रारूप डेटा फ्रेम प्राप्त करें मेरे पास स्ट्रिंग्स वाली सूचियों की एक सूची है। प्रत्येक उप-सूची की पहली स्ट्रिंग उस श्रेणी का वर्णन करती है जिसमें निम्न स्ट्रिंग्स हैं। मैं श्रेणी के लिए एक कॉलम और सामग्री के लिए एक (लंबे प्रारूप) डेटा फ्रेम प्राप्त करना चाहता हूं। मैं कैसे इस सूची से लंबे प्रारूप में एक डेटा फ्रेम प्राप्त कर सकते हैं:सूची

mylist <- list(
    c("A","lorem","ipsum"), 
    c("B","sed", "eiusmod", "tempor" ,"inci"), 
    c("C","aliq", "ex", "ea")) 

> mylist 
[[1]] 
[1] "A"  "lorem" "ipsum" 

[[2]] 
[1] "B"  "sed"  "eiusmod" "tempor" "incidunt" 

[[3]] 
[1] "C"  "aliquid" "ex"  "ea" 

यह इस डेटा फ्रेम

mydf <- data.frame(cate= c("A","A","B","B","B","B","C","C","C"), 
       cont= c("lorem","ipsum","sed", "eiusmod", "tempor","inci","aliq", "ex", "ea")) 

> mydf 
    cate cont 
1 A lorem 
2 A ipsum 
3 B  sed 
4 B eiusmod 
5 B tempor 
6 B incidunt 
7 C aliquid 
8 C  ex 
9 C  ea 

मैं पहले से ही श्रेणियों और सामग्री अलग कर लिया है की तरह दिखना चाहिए।

cate <- sapply(mylist, "[[",1) 
cont <- sapply(mylist, "[", -(1)) 

mydf प्राप्त करने के लिए कैसे आगे बढ़ें?

उत्तर

8

हम stack का उपयोग list 'केप' के साथ 'cont' के तत्वों के नामकरण के बाद कर सकते हैं।

setNames(stack(setNames(cont, cate))[2:1], c('cate', 'cont')) 
# cate cont 
#1 A lorem 
#2 A ipsum 
#3 B  sed 
#4 B eiusmod 
#5 B tempor 
#6 B inci 
#7 C aliq 
#8 C  ex 
#9 C  ea 
10

हम भी पहले से ही ओपी की पोस्ट में बनाया चर के साथ संयोजन में rep उपयोग कर सकते हैं।

dat <- data.frame(cat=rep(cate, lengths(cont)), 
        cont=unlist(cont)) 

तो वहाँ के रूप में क्या 'सर्वश्रेष्ठ' जवाब है के बारे में कुछ चर्चा नहीं हुई (यदि वहाँ भी एक है, जो मुझे शक है), यहाँ कुछ मानक (मामले प्रदर्शन मामलों में) 100000 की एक सूची के आधार पर कर रहे हैं, वैक्टर पर कार्रवाई करने के:

Unit: milliseconds 
    expr  min  lq  mean median  uq  max neval cld 
heroka 56.24516 67.98583 122.1209 82.35606 117.6017 391.8297 50 a 
    akrun 258.86939 283.10408 363.5425 331.50263 448.9134 578.1818 50 b 
ananda 47.72320 61.05269 132.2678 76.22913 218.8286 385.5709 50 a 

बेंचमार्किंग कोड मानता है कि चर cate और cont पहले से ही बनाई गई हैं के रूप में दोनों समाधान उन्हें का उपयोग करें।

heroka <- function(){ 
data.frame(cat=rep(cate, lengths(cont)), cont=unlist(cont)) 
} 

akrun <- function(){ 
    setNames(stack(setNames(cont, cate))[2:1], c('cate', 'cont')) 
} 

ananda <- function(){ 
    setorder(melt(as.data.table(transpose(mylist)), 
       id.vars = "V1", na.rm = TRUE), V1, variable)[] 
} 


mylist <- replicate(100000,c(sample(LETTERS[1:10],1),sample(LETTERS[1:10],sample(5)))) 
cate <- sapply(mylist, "[[",1) 
cont <- sapply(mylist, "[", -(1)) 

tests <- microbenchmark(
    heroka = heroka(), 
    akrun=akrun(),ananda=ananda(), 
    times=50 
) 
13

अपने मूल सूची और नहीं विभाजन का उपयोग वस्तुओं आपके द्वारा बनाई गई, तो आपको निम्न की कोशिश कर सकते हैं:

:

library(data.table) 
setorder(melt(as.data.table(transpose(mylist)), 
       id.vars = "V1", na.rm = TRUE), V1, variable)[] 
# V1 variable value 
# 1: A  V2 lorem 
# 2: A  V3 ipsum 
# 3: B  V2  sed 
# 4: B  V3 eiusmod 
# 5: B  V4 tempor 
# 6: B  V5 inci 
# 7: C  V2 aliq 
# 8: C  V3  ex 
# 9: C  V4  ea 

मस्ती के लिए, आप भी इनमें से एक कोशिश कर सकते हैं


library(dplyr) 
library(tidyr) 

data_frame(id = seq_along(mylist), mylist) %>% 
    unnest %>% 
    group_by(id) %>% 
    mutate(ind = mylist[1]) %>% 
    slice(2:n()) 

library(purrr) 
data_frame(
    value = mylist %>% map(~ .x[-1]) %>% unlist, 
    ind = mylist %>% map(~ rep(.x[1], length(.x)-1)) %>% unlist 
) 

ध्यान दें कि आप इस तथ्य से नाराज होंगे कि "purrr" में transpose फ़ंक्शन भी है, जिसका अर्थ है कि यदि आपके पास "डेटा.table" भी लोड है, तो आपको चीजों का उपयोग करने की आदत में जाना होगा data.table::transpose या purrr::transpose यदि आप उन कार्यों का उपयोग कर रहे हैं (जैसे मैंने मूल उत्तर में किया था)। मैंने परीक्षण नहीं किया है, लेकिन मेरा अनुमान है कि "data.table" अभी भी आपकी मूल सूची से सबसे तेज़ होगा।

4

बस एक और का उपयोग कर lapply

do.call(rbind, lapply(mylist, function(x) data.frame(cate = x[1], cont = x[-1]))) 

# cate cont 
#1 A lorem 
#2 A ipsum 
#3 B  sed 
#4 B eiusmod 
#5 B tempor 
#6 B inci 
#7 C aliq 
#8 C  ex 
#9 C  ea 
+2

कॉलिंग 'प्रत्येक आइटम के लिए data.frame' दर्दनाक सूची का आकार बढ़ने के साथ धीमी गति से होने जा रहा है विकल्प। – A5C1D2H2I1M1N2O1R2T1