2012-03-30 8 views
5

मैं freq की एक मेज पर आया था। आज मायने रखता है मुझे कच्चे मूल्यों के डेटा फ्रेम में विस्तार करना पड़ा। मैं ऐसा करने में सक्षम था लेकिन क्या सोच रहा था कि reshape पैकेज या data.table का उपयोग करने का कोई तेज़ तरीका है?डेटा को दोबारा बदलना (एक तेज़ तरीका)

मूल तालिका इस तरह देखा:

i1 i2 i3 i4 m f 
1 0 0 0 0 22 29 
2 1 0 0 0 30 50 
3 0 1 0 0 13 15 
4 0 0 1 0 1 6 
5 1 1 0 0 24 67 
6 1 0 1 0 5 12 
7 0 1 1 0 1 2 
8 1 1 1 0 10 22 
9 0 0 0 1 10 7 
10 1 0 0 1 27 30 
11 0 1 0 1 14 4 
12 0 0 1 1 1 0 
13 1 1 0 1 54 63 
14 1 0 1 1 8 10 
15 0 1 1 1 8 6 
16 1 1 1 1 57 51 

यहाँ dput का उपयोग कर डेटा का एक आसान हड़पने है:

dat <- structure(list(i1 = c(0L, 1L, 0L, 0L, 1L, 1L, 0L, 1L, 0L, 1L, 
0L, 0L, 1L, 1L, 0L, 1L), i2 = c(0L, 0L, 1L, 0L, 1L, 0L, 1L, 1L, 
0L, 0L, 1L, 0L, 1L, 0L, 1L, 1L), i3 = c(0L, 0L, 0L, 1L, 0L, 1L, 
1L, 1L, 0L, 0L, 0L, 1L, 0L, 1L, 1L, 1L), i4 = c(0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), m = c(22L, 30L, 
13L, 1L, 24L, 5L, 1L, 10L, 10L, 27L, 14L, 1L, 54L, 8L, 8L, 57L 
), f = c(29L, 50L, 15L, 6L, 67L, 12L, 2L, 22L, 7L, 30L, 4L, 0L, 
63L, 10L, 6L, 51L)), .Names = c("i1", "i2", "i3", "i4", "m", 
"f"), class = "data.frame", row.names = c(NA, -16L)) 

मेरे दृष्टिकोण (रों) डेटा नयी आकृति प्रदान करने (क्या कोई तेज़ तरीका है?):

#step 1: method 1 (in this case binding and stacking uses less code than reshape) 
dat2 <- data.frame(rbind(dat[,1:4], dat[, 1:4]), 
    sex = rep(c('m', 'f'), each=16), 
    n = c(dat$m, dat$f)) 
dat2 

#step 1: method 2  
dat3 <- reshape(dat, direction = "long", idvar = 1:4, 
    varying = list(c("m", "f")), 
    v.names = c("n"), 
    timevar = "sex", 
    times = c("m", "f")) 
    rownames(dat3) <- 1:nrow(dat3) 
    dat3 <- data.frame(dat3) 
    dat3$sex <- as.factor(dat3$sex) 

all.equal(dat3, dat2) #just to show both method 1 and 2 give the same data frame 

#step 2 
dat4 <- dat2[rep(seq_len(nrow(dat2)), dat2$n), 1:5] 
rownames(dat4) <- 1:nrow(dat4) 
dat4 

मुझे लगता है कि यह एक आम समस्या है जब आप किसी लेख से एक टेबल लेना चाहते हैं और इसे पुन: उत्पन्न करना चाहते हैं, तो इसके लिए कुछ अनपॅकिंग की आवश्यकता होती है। मैं खुद को और अधिक से अधिक कर रहा हूं और यह सुनिश्चित करना चाहता हूं कि मैं कुशल हूं।

उत्तर

7

यहां एक-लाइनर है।

dat2 <- ddply(dat, 1:4, summarize, sex = c(rep('m', m), rep('f', f))) 
2

मैं दूसरे चरण के लिए melt का उपयोग करता हूं और दूसरे के लिए ddply का उपयोग करता हूं।

library(reshape2) 
library(plyr) 
d <- ddply( 
    melt(dat, id.vars=c("i1","i2","i3","i4"), variable.name="sex"), 
    c("i1","i2","i3","i4","sex"), 
    summarize, 
    id=rep(1,value) 
) 
d$id <- cumsum(d$id) 
+0

मैं ली यह मेरे दृष्टिकोण से कहीं बेहतर है। यदि कोई भी अधिक कुशलता से कम नहीं होता है (कम कोड लेखन जो गति नहीं है) मैं इसे सही उत्तर के रूप में चिह्नित करूंगा। +1 –

+0

मैं इसे सही के रूप में चिह्नित कर रहा हूं। मुझे नहीं लगता कि कोई भी इस कोड की मात्रा को हरा सकता है। –

+0

फिर से जांचें :-) – Ramnath

5

और यहां एक आधार आर वन-लाइनर है।

dat2 <- cbind(dat[c(rep(1:nrow(dat), dat$m), rep(1:nrow(dat), dat$f)),1:4], 
       sex=c(rep("m",sum(dat$m)), rep("f", sum(dat$f)))) 

या, एक छोटे से अधिक आम तौर पर:

d1 <- dat[,1:4] 
d2 <- as.matrix(dat[,5:6]) 
dat2 <- cbind(d1[rep(rep(1:nrow(dat), ncol(d2)), d2),], 
       sex=rep(colnames(d2), colSums(d2))) 
+0

आधार +1 –

3

यह देखते हुए कि कोई भी एक data.table समाधान पोस्ट किया गया है (के रूप में मूल प्रश्न में सुझाव दिया)

library(data.table) 
DT <- as.data.table(dat) 
DT[,list(sex = rep(c('m','f'),c(m,f))), by= list(i1,i2,i3,i4)] 

या, और भी अधिक संक्षेप

DT[,list(sex = rep(c('m','f'),c(m,f))), by= 'i1,i2,i3,i4'] 
+0

में अच्छा काम 'सी (एम, एफ) '(और' सूची (i1, i2, i3, i4) ') कॉलम नाम वाले चर के संदर्भ में संशोधित किया जा सकता है? उदाहरण के लिए, एम और एफ कॉलम के बजाए, यदि मेरे पास 100 कॉलम हैं (Var99 के माध्यम से Var0 कहें) और प्रत्येक कॉलम का नाम टाइप नहीं करना चाहते थे। – dnlbrky

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