2012-02-12 10 views
6

मेरी एक सूची है जिसमें प्रत्येक सूची आइटम एक अलग आवृत्ति पाठ पर "तालिका()" का उपयोग करने से व्युत्पन्न शब्द आवृत्ति तालिका है। इसलिए, प्रत्येक तालिका एक अलग लंबाई है। मैं अब सूची को एक डेटा फ्रेम में परिवर्तित करना चाहता हूं जिसमें प्रत्येक कॉलम एक शब्द है प्रत्येक पंक्ति एक नमूना पाठ है। यहाँ मेरी डेटा की एक डमी उदाहरण है:आवृत्ति सारणी को एक डेटा फ्रेम में मिलाएं

> class(myList[[3]]) 
[1] "table" 

> myList[[3]] 

     ask  can country  do  for  not what  you your 
    2  2  2  2  2  2  1  2  2  2 

मैं अब एक ही डेटा फ्रेम में यह सूची (MyList) बदलने की आवश्यकता:

t1<-table(strsplit(tolower("this is a test in the event of a real word file you would see many more words here"), "\\W")) 

t2<-table(strsplit(tolower("Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal"), "\\W")) 

t3<-table(strsplit(tolower("Ask not what your country can do for you - ask what you can do for your country"), "\\W")) 

myList <- list(t1, t2, t3) 

हां, तो एक संरचना इस तरह की हो जाता है। मैंने सोचा कि मैं इसे यहां क्या किया जाता है, इसके साथ मैं इसे कर सकता हूं (http://ryouready.wordpress.com/2009/01/23/r-combining-vectors-or-data-frames-of-unequal- लंबाई-में-एक-डेटा-फ्रेम /), उदाहरण के लिए

library(plyr) 
l <- myList 
do.call(rbind.fill, l) 

लेकिन ऐसा लगता है कि मेरी "टेबल" ऑब्जेक्ट्स अच्छी नहीं खेलती हैं। मैंने उन्हें डीएफएस और वैक्टरों में बदलने की कोशिश की, लेकिन इनमें से कोई भी काफी सही काम नहीं कर पाया।

+0

ओह प्रतीक्षा करें, मेरे उत्तर में मैंने माना है कि आप प्रत्येक तालिका के लिए एक अलग डेटा.फ्रेम कॉलम चाहते थे .. क्या आप उससे अलग प्रारूप के बाद थे? –

उत्तर

4
freqs.list <- mapply(data.frame,Words=seq_along(myList),myList,SIMPLIFY=FALSE,MoreArgs=list(stringsAsFactors=FALSE)) 
freqs.df <- do.call(rbind,freqs.list) 
res <- reshape(freqs.df,timevar="Words",idvar="Var1",direction="wide") 
head(res) 
+0

ग्रेगरी, यह समाधान सबसे कुशल है, धन्यवाद! – litlogger

1

यहां एक सुरुचिपूर्ण तरीका है जो काम पूरा हो जाता है। मैं वहाँ सिर्फ इस लिए है एक 1-लाइनर यकीन है, लेकिन मुझे पता नहीं है जहां या तो:

myList <- list(t1=t1, t2=t2, t3=t3) 
    myList <- lapply(myList,as.data.frame,stringsAsFactors = FALSE) 
    Words <- unique(unlist(lapply(myList,function(x) x[,1]))) 
    DFmerge <- data.frame(Words=Words) 
    for (i in 1:3){ 
     DFmerge <- merge(DFmerge,myList[[i]],by.x="Words",by.y="Var1",all.x=TRUE) 
    } 
    colnames(DFmerge) <- c("Words","t1","t2","t3") 

और थोड़ा और चारों ओर देख, यहाँ एक और तरीका है कि उत्पादन से जुड़ा हुआ ब्लॉग पोस्ट में है कि के समान देता है : [संपादित करें: अब काम करता है]

myList <- list(t1=t1, t2=t2, t3=t3) 
    myList <- lapply(myList,function(x) { 
     A <- as.data.frame(matrix(unlist(x),nrow=1)) 
     colnames(A) <- names(x) 
     A[,colnames(A) != ""] 
     } 
    ) 
    do.call(rbind.fill,myList) 

भी बदसूरत, तो हो सकता है कि एक बेहतर उत्तर अभी भी साथ आएगा।

+0

धन्यवाद टिम, मैं लूप के लिए बचने की उम्मीद कर रहा था, लेकिन ऐसा लगता है कि यह काम पूरा हो गया है। मैं फिर डीएफ को स्थानांतरित कर सकता हूं और थोड़ा छंटनी कर सकता हूं ताकि शब्द कॉलम नाम हों। । । फिर भी, मुझे लगता है कि एक प्लीयर आधारित समाधान होना चाहिए। । । । – litlogger

+0

@ दूसरी विधि @litlogger, अभी भी बदसूरत, अब काम करता है और लूप –

+0

के लिए एक से बचाता है और मुझे उल्लेख करना चाहिए, विराम चिह्न, उदा। '" - "' '' '' '' '' '' '' '' ''में बदल गया, और इससे' rbind.fill()' के लिए त्रुटियां हुईं। मैंने उन्हें अज्ञात 'लापली' समारोह में फेंक दिया। बस एफवाईआई, अगर वांछित नहीं था –

7

1. चिड़ियाघर। चिड़ियाघर पैकेज में एक मल्टीवे मर्ज फ़ंक्शन है जो इसे कॉम्पैक्ट कर सकता है। lapply एक चिड़ियाघर वस्तु को myList के प्रत्येक घटक धर्मान्तरित और फिर हम बस उन्हें सब विलय:

# optionally add nice names to the list 
names(myList) <- paste("t", seq_along(myList), sep = "") 

library(zoo) 
fz <- function(x)with(as.data.frame(x, stringsAsFactors=FALSE), zoo(Freq, Var1))) 
out <- do.call(merge, lapply(myList, fz)) 

ऊपर रिटर्न बहुविविध चिड़ियाघर श्रृंखला है, जिसमें "कई बार" "a", "ago", आदि कर रहे हैं लेकिन एक डेटा अगर फ्रेम परिणाम वांछित थे तो यह सिर्फ as.data.frame(out) का मामला था।

2. घटाएं। यहां दूसरा समाधान है। यह आर

की
merge1 <- function(x, y) merge(x, y, by = 1, all = TRUE) 
out <- Reduce(merge1, lapply(myList, as.data.frame, stringsAsFactors = FALSE)) 

# optionally add nice names 
colnames(out)[-1] <- paste("t", seq_along(myList), sep = "") 

3. xtabs कोर में Reduce उपयोग करता है। यह एक सूची में नाम कहते हैं और फिर आवृत्तियों, नाम और एक लंबी वेक्टर प्रत्येक उन्हें वापस डाल के रूप में समूहों के अर्क एक साथ xtabs का उपयोग कर:

names(myList) <- paste("t", seq_along(myList)) 

xtabs(Freq ~ Names + Group, data.frame(
    Freq = unlist(lapply(myList, unname)), 
    Names = unlist(lapply(myList, names)), 
    Group = rep(names(myList), sapply(myList, length)) 
)) 

बेंचमार्क

rbenchmark का उपयोग कर समाधान के कुछ बेंचमार्किंग पैकेज हमें निम्न मिलता है जो इंगित करता है कि चिड़ियाघर समाधान नमूना डेटा पर सबसे तेज़ है और तर्कसंगत रूप से सबसे सरल भी है।

> t1<-table(strsplit(tolower("this is a test in the event of a real word file you would see many more words here"), "\\W")) 
> t2<-table(strsplit(tolower("Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal"), "\\W")) 
> t3<-table(strsplit(tolower("Ask not what your country can do for you - ask what you can do for your country"), "\\W")) 
> myList <- list(t1, t2, t3) 
> 
> library(rbenchmark) 
> library(zoo) 
> names(myList) <- paste("t", seq_along(myList), sep = "") 
> 
> benchmark(xtabs = { 
+ names(myList) <- paste("t", seq_along(myList)) 
+ xtabs(Freq ~ Names + Group, data.frame(
+ Freq = unlist(lapply(myList, unname)), 
+ Names = unlist(lapply(myList, names)), 
+ Group = rep(names(myList), sapply(myList, length)) 
+)) 
+ }, 
+ zoo = { 
+ fz <- function(x) with(as.data.frame(x, stringsAsFactors=FALSE), zoo(Freq, Var1)) 
+ do.call(merge, lapply(myList, fz)) 
+ }, 
+ Reduce = { 
+ merge1 <- function(x, y) merge(x, y, by = 1, all = TRUE) 
+ Reduce(merge1, lapply(myList, as.data.frame, stringsAsFactors = FALSE)) 
+ }, 
+ reshape = { 
+ freqs.list <- mapply(data.frame,Words=seq_along(myList),myList,SIMPLIFY=FALSE,MoreArgs=list(stringsAsFactors=FALSE)) 
+ freqs.df <- do.call(rbind,freqs.list) 
+ reshape(freqs.df,timevar="Words",idvar="Var1",direction="wide") 
+ }, replications = 10, order = "relative", columns = c("test", "replications", "relative")) 
    test replications relative 
2  zoo   10 1.000000 
4 reshape   10 1.090909 
1 xtabs   10 1.272727 
3 Reduce   10 1.272727 

जोड़ा गया: दूसरा समाधान।

जोड़ा गया: तीसरा समाधान।

जोड़ा गया: बेंचमार्क।

+0

धन्यवाद जी के तहत एक पंक्ति में समूहीकृत किया गया है, लेकिन जब मैं आपका कोड उदाहरण चलाता हूं, तो मुझे एक त्रुटि मिलती है: eval में त्रुटि (विकल्प (expr), डेटा, enclos = parent.frame()): संख्यात्मक 'envir' तर्क लंबाई की – litlogger

+0

@litlogger, इसे ठीक कर दिया है। –

संबंधित मुद्दे