2011-01-21 13 views
11

मैं कार्योंडेटाफ्रेम की प्रत्येक पंक्ति में एन फ़ंक्शंस की एक सूची लागू करें?

funs <- list(fn1 = function(x) x^2, 
      fn2 = function(x) x^3,    
      fn3 = function(x) sin(x), 
      fn4 = function(x) x+1) 
#in reality these are all f = splinefun() 

की एक सूची है और मैं एक dataframe है:

mydata <- data.frame(x1 = c(1, 2, 3, 2), 
        x2 = c(3, 2, 1, 0), 
        x3 = c(1, 2, 2, 3), 
        x4 = c(1, 2, 1, 2)) 
#actually a 500x15 dataframe of 500 samples from 15 parameters 

मैं पंक्तियों में से प्रत्येक के लिए, मैं में से प्रत्येक पर समारोह जे मूल्यांकन करना चाहते हैं जे कॉलम और परिणाम योग:

unlist(funs) 
attach(mydata) 
a <- rep(NA,4) 
for (i in 1:4) { 
    a[i] <- sum(fn1(x1[i]), fn2(x2[i]), fn3(x3[i]), fn4(x4[i])) 
} 

मैं इसे कुशलतापूर्वक कैसे कर सकता हूं? क्या plyr कार्यों को लागू करने के लिए यह एक उचित अवसर है? यदि हां, तो कैसे?

बोनस प्रश्न: a[4]NA क्यों है?

क्या यह plyr से फ़ंक्शंस का उपयोग करने के लिए उपयुक्त समय है, यदि ऐसा है, तो मैं ऐसा कैसे कर सकता हूं?

+1

@abe तीसरे कोड स्निपेट के लिए, आपको या तो 'अनलिस्ट (मज़ेदार)' और 'संलग्न करें (mydata)' या 'मज़े $ fn1' और' mydata $ x1' –

+0

@ सुधार के लिए डेविड धन्यवाद का उपयोग करें, I इसे प्रतिबिंबित करने के लिए कोड बदल दिया है- लेकिन यह वास्तव में उस गड़बड़ी है जिसे मैं टालना चाहता हूं। – Abe

+2

ठीक है, बोनस बिंदु के लिए, जवाब यह है कि mydata $ x4 या उस डेटाफ्रेम के किसी भी कॉलम में कोई चौथा तत्व नहीं है। एक और टिप्पणी .. बस अनलिस्ट (मज़ेदार) टाइप करना कुछ भी नहीं करता है जब तक कि आप कुछ नतीजे निर्दिष्ट न करें। कार्यात्मक प्रोग्रामिंग में आपका स्वागत है। –

उत्तर

9

अपने कोड स्निपेट की उपेक्षा करने और अपने प्रारंभिक विनिर्देश के लिए चिपके हुए है कि आप स्तंभ संख्या जे पर समारोह जे लागू करते हैं और फिर "परिणाम योग" करना चाहते हैं ... आप कर सकते हैं:

mapply(do.call, funs, lapply(mydata, list)) 
#  [,1] [,2]  [,3] [,4] 
# [1,] 1 27 0.8414710 2 
# [2,] 4 8 0.9092974 3 
# [3,] 9 1 0.9092974 3 

मुझे यकीन नहीं था कि आप अब किस तरह से परिणाम जोड़ना चाहते हैं (यानी पंक्ति-वार या कॉलम-वार), ताकि आप या तो इस मैट्रिक्स पर rowSums या colSums कर सकें। E.g:

colSums(mapply(do.call, funs, lapply(mydata, list))) 
# [1] 14.000000 36.000000 2.660066 8.000000 
+0

धन्यवाद; मैं rowSums का उपयोग करूंगा लेकिन यह वह अवधारणा है जिसे मैं ढूंढ रहा था। – Abe

+0

मुझे समझ में नहीं आता कि आखिरी सूची क्या करती है, यह करने के लिए दूसरा तर्क नहीं है। समारोह में तर्कों की एक सूची है? – Abe

+0

मैंने थोड़ा ऊपर दूसरी अभिव्यक्ति संपादित की है (आपको 'as.list' करने की आवश्यकता नहीं है)। सूचियों की सूची में 'mydata' को चालू करने के लिए आपको' lapply (mydata, list) 'करने की आवश्यकता है। फिर 'मप्ली' प्रत्येक कार्य को 'मज़ेदार 'में लेने के लिए' do.call' का कारण बनता है, और' lapply (mydata, list) 'के संबंधित सूची-सदस्य को लेता है, जो स्वयं ही एक सूची है। –

4

क्यों सभी 4 के लिए एक फ़ंक्शन नहीं लिखते हैं और इसे डेटा फ्रेम पर लागू नहीं करते हैं? सभी अपने कार्यों vectorized हैं, और इसलिए splinefun है, और यह काम करेगा:

fun <- function(df) 
    cbind(df[, 1]^2, df[, 2]^3, sin(df[, 3]), df[, 4] + 1) 

rowSums(fun(mydata)) 

यह "foring" या पंक्तियों पर "लागू करने" की तुलना में काफी अधिक कुशल है।

0

मैं plyr::each उपयोग करने की कोशिश:

library(plyr) 
sapply(mydata, each(min, max)) 
    x1 x2 x3 x4 
min 1 0 1 1 
max 3 3 3 2 

और यह ठीक काम करता है, लेकिन जब मैं कस्टम कार्यों पारित मैं:

sapply(mydata, each(fn1, fn2)) 
Error in proto[[i]] <- fs[[i]](x, ...) : 
    more elements supplied than there are to replace 

each बहुत संक्षिप्त प्रलेखन है, मैं काफी क्या नहीं मिलता है समस्या।

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