Lapply और do.call में क्या अंतर है?


143

मैं हाल ही में आर सीख रहा हूं और दो फ़ंक्शन द्वारा भ्रमित हूं: lapplyऔर do.call। ऐसा लगता है कि वे mapलिस्प में कार्य करने के लिए समान हैं । लेकिन इतने अलग नाम के साथ दो कार्य क्यों हैं? R केवल एक फ़ंक्शन का उपयोग क्यों नहीं करता है map?

जवाबों:


126

एक फ़ंक्शन है जिसे Mapअन्य भाषाओं में नक्शे के समान कहा जा सकता है:

  • lapply एक्स के समान लंबाई की एक सूची देता है, जिनमें से प्रत्येक तत्व FUN को X के संबंधित तत्व पर लागू करने का परिणाम है।

  • do.call एक नाम या एक फ़ंक्शन से एक फ़ंक्शन कॉल का निर्माण और निष्पादित करता है और इसे पारित करने के लिए तर्कों की एक सूची।

  • Mapदिए गए वैक्टरों के संगत तत्वों के लिए एक फ़ंक्शन लागू होता है ... Mapएक साधारण आवरण होता है, mapplyजो सामान्य लिस्प के मैपकार (पुनर्नवीनीकरण किए जा रहे तर्कों के साथ) के समान परिणाम को सरल बनाने का प्रयास नहीं करता है। भविष्य के संस्करण परिणाम प्रकार के कुछ नियंत्रण की अनुमति दे सकते हैं।


  1. Map चारों ओर एक आवरण है mapply
  2. lapply का एक विशेष मामला है mapply
  3. इसलिए Mapऔर lapplyकई मामलों में समान होगा।

उदाहरण के लिए, यहाँ है lapply:

lapply(iris, class)
$Sepal.Length
[1] "numeric"

$Sepal.Width
[1] "numeric"

$Petal.Length
[1] "numeric"

$Petal.Width
[1] "numeric"

$Species
[1] "factor"

और उसी का उपयोग करते हुए Map:

Map(class, iris)
$Sepal.Length
[1] "numeric"

$Sepal.Width
[1] "numeric"

$Petal.Length
[1] "numeric"

$Petal.Width
[1] "numeric"

$Species
[1] "factor"

do.callएक फ़ंक्शन को इनपुट के रूप में लेता है और फ़ंक्शन के अपने अन्य तर्कों को विभाजित करता है। यह व्यापक रूप से उपयोग किया जाता है, उदाहरण के लिए, सरल संरचनाओं में सूचियों को इकट्ठा करने के लिए (अक्सर rbindया इसके साथ cbind)।

उदाहरण के लिए:

x <- lapply(iris, class)
do.call(c, x)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
   "numeric"    "numeric"    "numeric"    "numeric"     "factor" 

4
वास्तव में मैंने पाया do.callकि लगभग उसी तरह है जैसे applyकि लिस्प में
हनफेई सन

do.call(cbind, x)वर्तमान संस्करण होने वाला अंतिम उदाहरण मुझे नहीं देता Error in do.call(c, x) : 'what' must be a function or character string...
sindri_baldur

1
@snoram यह उदाहरण अभी भी काम करता है। फ़ंक्शन फ़ंक्शन cbind()से अलग है c(), और यद्यपि यह भी काम करता है, यह अलग-अलग परिणाम देता है।
एंड्री

61

lapplyएक सूची पर एक फ़ंक्शन लागू करता है, do.callएक फ़ंक्शन को तर्कों की सूची के साथ कॉल करता है। यह मेरे लिए काफी अंतर की तरह लग रहा है ...

एक सूची के साथ एक उदाहरण देने के लिए:

X <- list(1:3,4:6,7:9)

Lapply के साथ आपको सूची में हर तत्व का अर्थ इस तरह मिलता है:

> lapply(X,mean)
[[1]]
[1] 2

[[2]]
[1] 5

[[3]]
[1] 8

do.call एक त्रुटि देता है, जैसा कि तर्क "ट्रिम" 1 होने की उम्मीद करता है।

दूसरी ओर, rbindसभी तर्कों को भुनाता है। तो एक्स रोवे को बांधने के लिए, आप करते हैं:

> do.call(rbind,X)
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9

यदि आप उपयोग करते हैं lapply, तो आर rbindआपको सूची के प्रत्येक तत्व पर लागू करेगा , जो आपको यह बकवास देगा:

> lapply(X,rbind)
[[1]]
     [,1] [,2] [,3]
[1,]    1    2    3

[[2]]
     [,1] [,2] [,3]
[1,]    4    5    6

[[3]]
     [,1] [,2] [,3]
[1,]    7    8    9

मानचित्र जैसा कुछ होने के लिए, आपको आवश्यकता है ?mapply, जो पूरी तरह से कुछ अलग है। एक्स में हर तत्व का उदाहरण प्राप्त करने के लिए, लेकिन एक अलग ट्रिमिंग के साथ, आप इसका उपयोग कर सकते हैं:

> mapply(mean,X,trim=c(0,0.5,0.1))
[1] 2 5 8

34

lapplyके समान है map, do.callनहीं है। lapplyएक सूची के सभी तत्वों के लिए एक फ़ंक्शन लागू करता है, एक फ़ंक्शन को do.callकॉल करता है जहां सभी फ़ंक्शन तर्क एक सूची में हैं। एक के लिए तो nतत्व सूची, lapplyहै nसमारोह कॉल, और do.callसिर्फ एक समारोह कॉल है। तो इससे do.callकाफी अलग है lapply। आशा है कि यह आपके मुद्दे को स्पष्ट करेगा।

एक कोड उदाहरण:

do.call(sum, list(c(1, 2, 4, 1, 2), na.rm = TRUE))

तथा:

lapply(c(1, 2, 4, 1, 2), function(x) x + 1)

25

सबसे सरल शब्दों में:

  1. lapply () किसी सूची में प्रत्येक तत्व के लिए दिए गए फ़ंक्शन को लागू करता है, इसलिए कई फ़ंक्शन कॉल होंगे।

  2. do.call () संपूर्ण रूप से सूची में दिए गए फ़ंक्शन को लागू करता है, इसलिए केवल एक फ़ंक्शन कॉल है।

सीखने का सबसे अच्छा तरीका आर प्रलेखन में फ़ंक्शन उदाहरणों के साथ खेलना है।


12

lapply()एक मानचित्र जैसा कार्य है। do.call()फरक है। इसका उपयोग तर्कों को सूची में रखने के बजाए उन्हें प्रगणित करने के लिए किया जाता है। उदाहरण के लिए,

> do.call("+",list(4,5))
[1] 9

10

हालाँकि कई उत्तर दिए गए हैं, यहाँ संदर्भ के लिए मेरा उदाहरण है। मान लीजिए कि हमारे पास डेटा की एक सूची है:

L=list(c(1,2,3), c(4,5,6))

समारोह में lapply एक सूची देता है।

lapply(L, sum) 

उपरोक्त का अर्थ नीचे जैसा कुछ है।

list( sum( L[[1]]) , sum( L[[2]]))

अब do.call के लिए समान कार्य करते हैं

do.call(sum, L) 

इसका मतलब

sum( L[[1]], L[[2]])

हमारे उदाहरण में, यह 21 देता है। संक्षेप में, लंगोटी हमेशा एक सूची देता है जबकि रिटर्न प्रकार do.all वास्तव में निष्पादित कार्य पर निर्भर करता है।


5

दोनों के बीच अंतर हैं:

lapply(1:n,function,parameters)

=> यह 1, पैरामीटर को कार्य करने के लिए भेजता है => यह 2, पैरामीटर को फ़ंक्शन और इतने पर भेजता है

do.call 

बस एक वेक्टर के रूप में 1… n भेजता है और कार्य करने के लिए पैरामीटर

तो लागू करने में आप n फ़ंक्शन कॉल करते हैं, do.call में आपके पास बस एक है

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