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


129

मान लीजिए कि मेरे पास एक 2 मैट्रिक्स है और एक फ़ंक्शन है जो 2-वेक्टर को उसके एक तर्क के रूप में लेता है। मैं फ़ंक्शन को मैट्रिक्स की प्रत्येक पंक्ति में लागू करना चाहता हूं और एन-वेक्टर प्राप्त करना चाहता हूं। आर में यह कैसे करें?

उदाहरण के लिए, मैं एक 2D मानक सामान्य वितरण के घनत्व की गणना तीन बिंदुओं पर करना चाहूंगा:

bivariate.density(x = c(0, 0), mu = c(0, 0), sigma = c(1, 1), rho = 0){
    exp(-1/(2*(1-rho^2))*(x[1]^2/sigma[1]^2+x[2]^2/sigma[2]^2-2*rho*x[1]*x[2]/(sigma[1]*sigma[2]))) * 1/(2*pi*sigma[1]*sigma[2]*sqrt(1-rho^2))
}

out <- rbind(c(1, 2), c(3, 4), c(5, 6))

प्रत्येक पंक्ति में फ़ंक्शन कैसे लागू करें out?

आपके द्वारा निर्दिष्ट तरीके से फ़ंक्शन के बिंदुओं के अलावा अन्य तर्कों के लिए मान कैसे पारित करें?

जवाबों:


180

आप बस apply()फ़ंक्शन का उपयोग करें :

R> M <- matrix(1:6, nrow=3, byrow=TRUE)
R> M
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6
R> apply(M, 1, function(x) 2*x[1]+x[2])
[1]  4 10 16
R> 

यह एक मैट्रिक्स लेता है और प्रत्येक पंक्ति में एक (मूर्खतापूर्ण) फ़ंक्शन लागू करता है। आप चौथे, पांचवें, ... के रूप में फ़ंक्शन के लिए अतिरिक्त तर्क पास करते हैं apply()


धन्यवाद! क्या होगा अगर मैट्रिक्स की पंक्तियाँ फ़ंक्शन का पहला आर्ग नहीं है? यह निर्दिष्ट करने के लिए कि मैट्रिक्स की प्रत्येक पंक्ति किस फ़ंक्शन को दी गई है?
टिम

सहायता के लिए पढ़ें apply()- यह पंक्ति द्वारा स्वीप करता है (जब दूसरा arg 1 है, कॉलम द्वारा अन्य), और वर्तमान पंक्ति (या कॉल) हमेशा पहला तर्क है। इस तरह से चीजों को परिभाषित किया जाता है।
डिर्क एडल्डबुलेटेल

@Tim: यदि आप एक आंतरिक आर समारोह का उपयोग करें और पंक्ति पहले आर्ग नहीं है, कर के रूप में एक प्रकार की कटार किया था और अपने स्वयं के कस्टम समारोह बनाने जहां पंक्ति है पहले आर्ग।
जोरिस मेव्स

3
प्लायर पैकेज इन लागू प्रकारों की एक विस्तृत श्रृंखला प्रदान करता है। यह समानांतर प्रसंस्करण सहित अधिक कार्यक्षमता भी प्रदान करता है।
पॉल हेममस्ट्रा

6
@ cryptic0 यह उत्तर देर से है, लेकिन गुग्लर्स के लिए, लागू होने में दूसरा तर्क MARGINतर्क है। यहाँ इसका अर्थ है फ़ंक्शन को पंक्तियों (पहले आयाम में dim(M)) पर लागू करें। यदि यह 2 थे, तो यह फ़ंक्शन को कॉलम पर लागू करेगा।
डे नोवो

17

यदि आप सम या माध्य जैसे सामान्य कार्य लागू करना चाहते हैं, तो आपको इसका उपयोग करना चाहिए rowSumsयाrowMeans जब से वे apply(data, 1, sum)दृष्टिकोण से तेज हैं । अन्यथा, साथ रहना apply(data, 1, fun)। FUN तर्क के बाद आप अतिरिक्त तर्क पास कर सकते हैं (जैसा कि डिर्क पहले से ही सुझाया गया है):

set.seed(1)
m <- matrix(round(runif(20, 1, 5)), ncol=4)
diag(m) <- NA
m
     [,1] [,2] [,3] [,4]
[1,]   NA    5    2    3
[2,]    2   NA    2    4
[3,]    3    4   NA    5
[4,]    5    4    3   NA
[5,]    2    1    4    4

तो आप इस तरह से कुछ कर सकते हैं:

apply(m, 1, quantile, probs=c(.25,.5, .75), na.rm=TRUE)
    [,1] [,2] [,3] [,4] [,5]
25%  2.5    2  3.5  3.5 1.75
50%  3.0    2  4.0  4.0 3.00
75%  4.0    3  4.5  4.5 4.00

15

मैट्रिक्स की प्रत्येक पंक्ति में फ़ंक्शन को लागू करने का एक छोटा उदाहरण यहां दिया गया है। (यहां, फंक्शन लागू किया गया है हर पंक्ति को सामान्य करता है 1.)

नोट: इनपुट मैट्रिक्स के समान लेआउट प्राप्त करने के लिए उपयोग किए जाने वाले परिणाम को ट्रांसपोज़apply() किया जाना था ।t()A

A <- matrix(c(
  0, 1, 1, 2,
  0, 0, 1, 3,
  0, 0, 1, 3
), nrow = 3, byrow = TRUE)

t(apply(A, 1, function(x) x / sum(x) ))

परिणाम:

     [,1] [,2] [,3] [,4]
[1,]    0 0.25 0.25 0.50
[2,]    0 0.00 0.25 0.75
[3,]    0 0.00 0.25 0.75

6

पहला कदम फंक्शन ऑब्जेक्ट बना रहा होगा, फिर उसे लागू करना। यदि आप एक ऐसी मैट्रिक्स ऑब्जेक्ट चाहते हैं जिसमें समान पंक्तियों की संख्या हो, तो आप इसे पूर्वनिर्धारित कर सकते हैं और ऑब्जेक्ट का उपयोग कर सकते हैं [] रूप को सचित्र (अन्यथा लौटे मूल्य को एक वेक्टर में सरल किया जाएगा):

bvnormdens <- function(x=c(0,0),mu=c(0,0), sigma=c(1,1), rho=0){
     exp(-1/(2*(1-rho^2))*(x[1]^2/sigma[1]^2+
                           x[2]^2/sigma[2]^2-
                           2*rho*x[1]*x[2]/(sigma[1]*sigma[2]))) * 
     1/(2*pi*sigma[1]*sigma[2]*sqrt(1-rho^2))
     }
 out=rbind(c(1,2),c(3,4),c(5,6));

 bvout<-matrix(NA, ncol=1, nrow=3)
 bvout[] <-apply(out, 1, bvnormdens)
 bvout
             [,1]
[1,] 1.306423e-02
[2,] 5.931153e-07
[3,] 9.033134e-15

यदि आप अपने डिफ़ॉल्ट मापदंडों के अलावा अन्य का उपयोग करना चाहते हैं तो कॉल में फ़ंक्शन के बाद नामित तर्क शामिल होने चाहिए:

bvout[] <-apply(out, 1, FUN=bvnormdens, mu=c(-1,1), rho=0.6)

लागू () का उपयोग उच्च आयामी सरणियों पर भी किया जा सकता है और MARGIN तर्क एक वेक्टर के साथ-साथ एक पूर्णांक भी हो सकता है।


4

आवेदन अच्छी तरह से काम करता है, लेकिन काफी धीमा है। नीलमणि और vapply का उपयोग उपयोगी हो सकता है। dplyr की रॉवेज़ भी उपयोगी हो सकती है आइए एक उदाहरण देखें कि किसी भी डेटा फ़्रेम की पंक्ति वार उत्पाद कैसे करें।

a = data.frame(t(iris[1:10,1:3]))
vapply(a, prod, 0)
sapply(a, prod)

ध्यान दें कि vapply / sapply / apply का उपयोग करने से पहले वेरिएबल को असाइन करना अच्छा अभ्यास है क्योंकि यह समय को बहुत कम करता है। आइए देखें माइक्रोबेनमार्क परिणाम

a = data.frame(t(iris[1:10,1:3]))
b = iris[1:10,1:3]
microbenchmark::microbenchmark(
    apply(b, 1 , prod),
    vapply(a, prod, 0),
    sapply(a, prod) , 
    apply(iris[1:10,1:3], 1 , prod),
    vapply(data.frame(t(iris[1:10,1:3])), prod, 0),
    sapply(data.frame(t(iris[1:10,1:3])), prod) ,
    b %>%  rowwise() %>%
        summarise(p = prod(Sepal.Length,Sepal.Width,Petal.Length))
)

टी () का उपयोग कैसे किया जा रहा है, इस पर ध्यान दें


यह तुलना करने के लिए परिवार लागू अगर आप का इस्तेमाल किया और अधिक निष्पक्ष हो सकता है b <- t(iris[1:10, 1:3])और apply(b, 2 prod)
DaSpeeg

2

एक अन्य दृष्टिकोण यदि आप एकल मान के बजाय डेटासेट के किसी भिन्न भाग का उपयोग करना चाहते हैं rollapply(data, width, FUN, ...)। चौड़ाई के वेक्टर का उपयोग करने से आप डेटासेट की एक अलग विंडो पर एक फ़ंक्शन लागू कर सकते हैं। मैंने इसे अनुकूली फ़िल्टरिंग रूटीन बनाने के लिए उपयोग किया है, हालांकि यह बहुत कुशल नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.