2010-11-10 26 views
5

मैं क्यों ऐसा होता है में अंतर्दृष्टि की सराहना करेंगे और कैसे मैं इस अधिक अर्थपूर्ण हो सकती।क्यों sapply एक मैट्रिक्स है कि मैं स्थानांतरित करने के लिए की जरूरत है वापसी करता है, और फिर स्थानांतरित मैट्रिक्स एक dataframe से संलग्न नहीं होगा?

जब मैं sapply उपयोग करते हैं, मुझे यह पसंद है एक 3x2 मैट्रिक्स लौटने के लिए होगा, लेकिन यह एक 2x3 मैट्रिक्स देता है। ऐसा क्यों है? और इसे किसी अन्य डेटा फ्रेम से जोड़ना क्यों मुश्किल है?

a <- data.frame(id=c('a','b','c'), var1 = c(1,2,3), var2 = c(3,2,1)) 
out <- sapply(a$id, function(x) out = a[x, c('var1', 'var2')]) 
#out is 3x2, but I would like it to be 2x3 
#I then want to append t(out) (out as a 2x3 matrix) to b, a 1x3 dataframe 
b <- data.frame(var3=c(0,0,0)) 

जब मैं इन संलग्न करने के लिए प्रयास करते हैं,

b[,c('col2','col3')] <- t(out) 

त्रुटि है कि मैं मिलता है:

Warning message: 
In `[<-.data.frame`(`*tmp*`, , c("col2", "col3"), value = list(1, : 
    provided 6 variables to replace 2 variables 

हालांकि निम्नलिखित वांछित परिणाम देने के लिए प्रकट होता है:

rownames(out) <- c('col1', 'col2') 
b <- cbind(b, t(out)) 

मैं वें पर काम नहीं कर सकता ई चर:

b$var1/b$var2 

रिटर्न

Error in b$var1/b$var2 : non-numeric argument to binary operator 

धन्यवाद!

+1

आप इस डेटा के साथ क्या करने की कोशिश कर रहे हैं से कम से ddply एक नज़र है? आपका उदाहरण वास्तव में कुछ भी सार्थक नहीं करता है। – hadley

+2

@ हैडली: उदाहरण कम से कम, व्यावहारिक उदाहरण प्रदान करने के आर पोस्टिंग दिशानिर्देशों का पालन करता है। वास्तविक मामला बल्कि जटिल है, और जटिलता केंद्रीय प्रश्न से अलग हो जाएगी। एक टायलर श्रृंखला विस्तार का उपयोग कर 20 अलग-अलग पैरामीटर के लिए मॉडल की संवेदनशीलता का अनुमान लगाया गया कार्य, और इनपुट के रूप में 20x8 डेटाफ्रेम स्वीकार करता है। यदि आप चाहें तो मुझे एक पूर्ण पुनरुत्पादित उदाहरण भेजने में खुशी होगी, हालांकि यह अभी तक सार्वजनिक होने के लिए तैयार नहीं है। –

+1

आपको समझने में आसान कुछ और उस समस्या के सार को कैप्चर करने वाले कुछ के बीच एक सुखद माध्यम के लिए प्रयास करने की आवश्यकता है, जिसके साथ आप संघर्ष कर रहे हैं।आपके वर्तमान उदाहरण में ऐसा लगता है कि आप 'बी'' के बराबर होने की कोशिश कर रहे हैं। – hadley

उत्तर

3

DWin के जवाब पर विस्तार करने के लिए: यह आपके out वस्तु की संरचना को देखने के लिए मदद मिलेगी। यह बताता है कि b$var1/b$var2 आपकी अपेक्षाओं को क्यों नहीं करता है।

> out <- sapply(a$id, function(x) out = a[x, c('var1', 'var2')]) 
> str(out) # this isn't a data.frame or a matrix... 
List of 6 
$ : num 1 
$ : num 3 
$ : num 2 
$ : num 2 
$ : num 3 
$ : num 1 
- attr(*, "dim")= int [1:2] 2 3 
- attr(*, "dimnames")=List of 2 
    ..$ : chr [1:2] "var1" "var2" 
    ..$ : NULL 

कार्यों का apply परिवार वैक्टर और सरणियों पर काम करने की तैयार कर रहे हैं, तो आप जब उन्हें data.frames (जो आमतौर पर वैक्टर की सूची नहीं है) के साथ का उपयोग कर देखभाल करने के लिए की जरूरत है। आप इस तथ्य का उपयोग कर सकते हैं कि डेटा.फ्रेम lapply के साथ आपके लाभ के लिए सूचीबद्ध हैं।

> out <- lapply(a$id, function(x) a[x, c('var1', 'var2')]) # list of data.frames 
> out <- do.call(rbind, out) # data.frame 
> b <- cbind(b,out) 
> str(b) 
'data.frame': 3 obs. of 4 variables: 
$ var3: num 0 0 0 
$ var1: num 1 2 3 
$ var2: num 3 2 1 
$ var3: num 0 0 0 
> b$var1/b$var2 
[1] 0.3333333 1.0000000 3.0000000 
2

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

> tsapply <- function(...) t(sapply(...)) 
> out <- tsapply(a$id, function(x) out = a[x, c('var1', 'var2')]) 
> out 
    var1 var2 
[1,] 1 3 
[2,] 2 2 
[3,] 3 1 

... एक 3 x 2 मैट्रिक्स: आप इसे पसंद नहीं है, तो आप एक नया समारोह tsapply कि स्थानांतरित मूल्यों वापस आ जाएगी परिभाषित कर सकते हैं।

+1

तकनीकी रूप से, 'आउट' एक मैट्रिक्स नहीं है। यह 'dim' और' dimnames' विशेषताओं वाली एक सूची है। जैसे '%% *% टी (आउट)' विफल रहता है। –

+0

आर को छोड़कर यह सोचता है कि यह एक मैट्रिक्स है:> is.matrix (आउट) [1] सत्य –

1

plyr पैकेज

a <- data.frame(id=c('a','b','c'), var1 = c(1,2,3), var2 = c(3,2,1)) 

library(plyr) 
ddply(a, "id", function(x){ 
    out <- cbind(O1 = rnorm(nrow(x), x$var1), O2 = runif(nrow(x))) 
    out 
}) 
संबंधित मुद्दे

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