खोज…


टिप्पणियों

*apply परिवार में एक समारोह एक लूप के for एक अमूर्त है। छोरों के for तुलना में *apply कार्यों के निम्नलिखित फायदे हैं:

  1. लिखने के लिए कम कोड की आवश्यकता होती है।
  2. एक पुनरावृत्ति काउंटर नहीं है।
  3. मध्यवर्ती परिणामों को संग्रहीत करने के लिए अस्थायी चर का उपयोग नहीं करता है।

हालांकि for छोरों अधिक सामान्य होते हैं और हमें और अधिक जटिल गणनाओं कि हमेशा का उपयोग कर ऐसा करने के लिए तुच्छ नहीं हैं को प्राप्त करने के लिए अनुमति नियंत्रण दे सकते हैं *apply कार्य करता है।

लूप्स के for संबंध और *apply कार्यों को *apply के for छोरों के for प्रलेखन में समझाया गया है।

*apply सदस्य परिवार को *apply

फ़ंक्शंस के *apply परिवार में एक ही सिद्धांत के कई प्रकार होते हैं जो मुख्य रूप से उस तरह के आउटपुट पर आधारित होते हैं जो वे वापस करते हैं।

समारोह इनपुट उत्पादन
apply matrix , data.frame , या array वेक्टर या मैट्रिक्स (लौटे प्रत्येक तत्व की लंबाई के आधार पर)
sapply वेक्टर या list वेक्टर या मैट्रिक्स (लौटे प्रत्येक तत्व की लंबाई के आधार पर)
lapply वेक्टर या list list
vapply वेक्टर या `सूची उपयोगकर्ता द्वारा निर्दिष्ट वर्ग के वेक्टर या मैट्रिक्स (लौटे प्रत्येक तत्व की लंबाई के आधार पर)
mapply कई वैक्टर, lists या एक संयोजन list

"उदाहरण" देखें कि इनमें से प्रत्येक फ़ंक्शन का उपयोग कैसे किया जाता है।

लागू के साथ अनाम कार्यों का उपयोग करें

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

आइए iris डेटासेट का उपयोग इस विचार को समझने के लिए करें। iris डेटासेट में 3 प्रजातियों के 150 फूल हैं। आइए देखें कि यह डेटासेट कैसे संरचित है:

> head(iris)

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1         5.1          3.5          1.4         0.2  setosa
2         4.9          3.0          1.4         0.2  setosa
3         4.7          3.2          1.3         0.2  setosa
4         4.6          3.1          1.5         0.2  setosa
5         5.0          3.6          1.4         0.2  setosa
6         5.4          3.9          1.7         0.4  setosa

अब, कल्पना कीजिए कि आप इनमें से प्रत्येक चर का मतलब जानना चाहते हैं। इस को हल करने के एक तरीका यह एक का उपयोग हो सकता है for पाश, लेकिन आर प्रोग्रामर अक्सर का उपयोग करेगी apply (वजहों, टिप्पणियां देखने के लिए):

> apply(iris[1:4], 2, mean)

Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    5.843333     3.057333     3.758000     1.199333
  • पहले पैरामीटर में, हम केवल पहले 4 कॉलम को शामिल करने के लिए iris को पूरा करते हैं, क्योंकि mean केवल संख्यात्मक डेटा पर काम करता है।
  • के दूसरे पैरामीटर मान 2 इंगित करता है कि हम स्तंभ केवल (आर × ग सरणी के दूसरे सबस्क्रिप्ट) पर काम करना चाहते हैं; 1 पंक्ति का मतलब देना होगा।

उसी तरह हम अधिक सार्थक मूल्यों की गणना कर सकते हैं:

# standard deviation
apply(iris[1:4], 2, sd)
# variance
apply(iris[1:4], 2, var)

कैविएट : आर में कुछ बिल्ट-इन फ़ंक्शंस हैं जो कॉलम और रो रकम की गणना के लिए बेहतर हैं और इसका मतलब है: colMeans और rowMeans

अब, चलो एक अलग और अधिक सार्थक कार्य करते हैं: आइए केवल उन मानों के लिए माध्य की गणना करें जो 0.5 से बड़े हैं। उसके लिए, हम अपना mean फ़ंक्शन बनाएंगे।

> our.mean.function <- function(x) { mean(x[x > 0.5]) }
> apply(iris[1:4], 2, our.mean.function)

Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    5.843333     3.057333     3.758000     1.665347

( Petal.Width के मतलब में अंतर पर ध्यान दें)

लेकिन, क्या होगा यदि हम अपने बाकी कोड में इस फ़ंक्शन का उपयोग नहीं करना चाहते हैं? फिर, हम एक अनाम फ़ंक्शन का उपयोग कर सकते हैं, और अपना कोड इस तरह लिख सकते हैं:

apply(iris[1:4], 2, function(x) { mean(x[x > 0.5]) })

इसलिए, जैसा कि हमने देखा है, हम केवल एक लाइन का उपयोग करके डेटासेट के कॉलम या पंक्तियों पर एक ही ऑपरेशन को निष्पादित करने के लिए apply का उपयोग कर सकते हैं।

चेतावनी: चूंकि apply रिटर्न निर्दिष्ट समारोह के परिणामों की लंबाई के आधार उत्पादन की बहुत अलग प्रकार के हैं, यह उन मामलों में जहां आप सहभागी काम नहीं कर रहे में सबसे अच्छा विकल्प नहीं हो सकता। अन्य में से कुछ *apply परिवार के कार्य थोड़ा अधिक पूर्वानुमान योग्य हैं (रिमार्क्स देखें)।

थोक फ़ाइल लोड हो रहा है

बड़ी संख्या में फ़ाइलों के लिए जिन्हें एक समान प्रक्रिया में और अच्छी तरह से संरचित फ़ाइल नामों के साथ संचालित करने की आवश्यकता हो सकती है।

सबसे पहले एक्सेस किए जाने वाले फ़ाइल नामों का एक वेक्टर बनाया जाना चाहिए, इसके लिए कई विकल्प हैं:

  • paste0() साथ मैन्युअल रूप से वेक्टर बनाना paste0()

     files <- paste0("file_", 1:100, ".rds")
    
  • फ़ाइल प्रकार के लिए regex खोज शब्द के साथ list.files() का उपयोग करते हुए, नियमित अभिव्यक्ति ( regex ) के ज्ञान की आवश्यकता होती है यदि उसी प्रकार की अन्य फाइलें निर्देशिका में हों।

     files <- list.files("./", pattern = "\\.rds$", full.names = TRUE)
    

जहाँ X उपयोग की जाने वाली फ़ाइलों के नामकरण के एक वेक्टर का उपयोग किया जाता है।

lapply एक सूची के तत्व के रूप में प्रत्येक प्रतिक्रिया का उत्पादन करेगा।

readRDS .rds फ़ाइलों के लिए विशिष्ट है और प्रक्रिया के आवेदन के आधार पर बदल जाएगा।

my_file_list <- lapply(files, readRDS)

यह आवश्यक रूप से परीक्षण के लिए लूप से अधिक तेज नहीं है, लेकिन सभी फाइलों को स्पष्ट रूप से निर्दिष्ट किए बिना सूची के एक तत्व होने की अनुमति देता है।

अंत में, हमें अक्सर एक साथ कई पैकेज लोड करने की आवश्यकता होती है। यह ट्रिक उन सभी पुस्तकालयों पर library() लागू करके इसे बहुत आसानी से कर सकती है जिन्हें हम आयात करना चाहते हैं:

lapply(c("jsonlite","stringr","igraph"),library,character.only=TRUE)

कई `data.frames` (` lapply`, `mapply`) का संयोजन

इस अभ्यास में, हम चार बूटस्ट्रैप रैखिक प्रतिगमन मॉडल उत्पन्न करेंगे और इन मॉडलों के सारांश को एक एकल डेटा फ्रेम में संयोजित करेंगे।

library(broom)

#* Create the bootstrap data sets
BootData <- lapply(1:4,
                   function(i) mtcars[sample(1:nrow(mtcars),
                                             size = nrow(mtcars),
                                             replace = TRUE), ])

#* Fit the models
Models <- lapply(BootData,
                 function(BD) lm(mpg ~ qsec + wt + factor(am),
                                 data = BD))

#* Tidy the output into a data.frame
Tidied <- lapply(Models,
                 tidy)

#* Give each element in the Tidied list a name
Tidied <- setNames(Tidied, paste0("Boot", seq_along(Tidied)))

इस बिंदु पर, हम data.frame में नाम सम्मिलित करने के लिए दो दृष्टिकोण ले सकते हैं।

#* Insert the element name into the summary with `lapply`
#* Requires passing the names attribute to `lapply` and referencing `Tidied` within
#* the applied function.
Described_lapply <- 
 lapply(names(Tidied),
        function(nm) cbind(nm, Tidied[[nm]]))

Combined_lapply <- do.call("rbind", Described_lapply)

#* Insert the element name into the summary with `mapply`
#* Allows us to pass the names and the elements as separate arguments.
Described_mapply <- 
 mapply(
  function(nm, dframe) cbind(nm, dframe),
  names(Tidied),
  Tidied,
  SIMPLIFY = FALSE)

Combined_mapply <- do.call("rbind", Described_mapply)

यदि आप magrittr शैली की पाइप के प्रशंसक हैं, तो आप पूरे कार्य को एक ही श्रृंखला में पूरा कर सकते हैं (हालांकि ऐसा करना समझदारी नहीं हो सकती है यदि आपको किसी मध्यस्थ वस्तु की आवश्यकता है, जैसे कि मॉडल ऑब्जेक्ट्स):

library(magrittr)
library(broom)
Combined <- lapply(1:4,
                   function(i) mtcars[sample(1:nrow(mtcars),
                                             size = nrow(mtcars),
                                             replace = TRUE), ]) %>%
 lapply(function(BD) lm( mpg ~ qsec + wt + factor(am), data = BD)) %>%
 lapply(tidy) %>%
 setNames(paste0("Boot", seq_along(.))) %>%
 mapply(function(nm, dframe) cbind(nm, dframe),
        nm = names(.),
        dframe = .,
        SIMPLIFY = FALSE) %>%
 do.call("rbind", .)

अंतर्निहित कार्यों का उपयोग करना

अंतर्निहित कार्य: lapply (), sapply (), और mapply ()

आर बिल्ट-इन फंक्शंस के साथ आता है, जिनमें से शायद सबसे प्रसिद्ध कार्य के परिवार हैं। यहाँ कुछ सबसे आम लागू कार्यों का विवरण दिया गया है:

  • lapply() = एक सूची को एक तर्क के रूप में लेता है और सूची में निर्दिष्ट फ़ंक्शन को लागू करता है।
  • sapply() एक ही = के रूप में lapply() लेकिन एक वेक्टर या एक मैट्रिक्स के लिए उत्पादन को सरल बनाने के प्रयास किए गए।
    • vapply() का एक संस्करण = sapply() है, जिसमें उत्पादन वस्तु के प्रकार निर्दिष्ट किया जाना चाहिए।
  • mapply() की तरह = lapply() लेकिन निर्दिष्ट फ़ंक्शन का इनपुट के रूप में कई वैक्टर पारित कर सकते हैं। sapply() तरह सरलीकृत किया जा सकता है।
    • Map() mapply() SIMPLIFY = FALSE साथ mapply() करने के लिए एक उपनाम Map() है।

lapply ()

lapply() का उपयोग दो अलग-अलग पुनरावृत्तियों के साथ किया जा सकता है:

  • lapply(variable, FUN)
  • lapply(seq_along(variable), FUN)
# Two ways of finding the mean of x
set.seed(1)
df <- data.frame(x = rnorm(25), y = rnorm(25))
lapply(df, mean)
lapply(seq_along(df), function(x) mean(df[[x]))

sapply ()

sapply() या तो एक वेक्टर या एक मैट्रिक्स के लिए अपने आउटपुट को हल करने का प्रयास करेगा।

# Two examples to show the different outputs of sapply()
sapply(letters, print)  ## produces a vector
x <- list(a = 1:10, beta = exp(-3:3), logic = c(TRUE,FALSE,FALSE,TRUE))
sapply(x, quantile)  ## produces a matrix

mapply ()

mapply() बहुत काम करता है lapply() को छोड़कर यह कई वैक्टर को इनपुट के रूप में ले सकता है (इसलिए lapply() लिए m)।

mapply(sum, 1:5, 10:6, 3) # 3 will be "recycled" by mapply

उपयोगकर्ता द्वारा परिभाषित क्रियाओं का उपयोग करना

उपयोगकर्ता-परिभाषित फ़ंक्शंस

उपयोगकर्ता जटिलता की डिग्री बदलती के लिए अपने स्वयं के कार्य कर सकते हैं। Hadley Wickham द्वारा निम्नलिखित उदाहरण कार्यात्मक हैं:

randomise <- function(f) f(runif(1e3))
        
lapply2 <- function(x, f, ...) {
    out <- vector("list", length(x))
    for (i in seq_along(x)) {
        out[[i]] <- f(x[[i]], ...)
    }
    out
}

पहले मामले में, randomise एकल तर्क f स्वीकार करता है, और इसे यूनिफ़ॉर्म यादृच्छिक चर के नमूने पर कहता है। तुल्यता प्रदर्शित करने के लिए, हम नीचे set.seed कहते हैं:

set.seed(123)
randomise(mean)
#[1] 0.4972778
    
set.seed(123)
mean(runif(1e3))
#[1] 0.4972778


set.seed(123)
randomise(max)
#[1] 0.9994045

set.seed(123)
max(runif(1e3))
#[1] 0.9994045

दूसरा उदाहरण base::lapply का पुन: कार्यान्वयन है base::lapply , जो किसी सूची ( x ) में प्रत्येक तत्व के लिए एक ऑपरेशन ( f ) लागू करने के लिए कार्यात्मक का उपयोग करता है। ... पैरामीटर के लिए अतिरिक्त तर्क पारित करने के लिए अनुमति देता है f जैसे, na.rm में विकल्प mean समारोह:

lapply(list(c(1, 3, 5), c(2, NA, 6)), mean)
# [[1]]
# [1] 3
# 
# [[2]]
# [1] NA

lapply2(list(c(1, 3, 5), c(2, NA, 6)), mean)
# [[1]]
# [1] 3
# 
# [[2]]
# [1] NA


lapply(list(c(1, 3, 5), c(2, NA, 6)), mean, na.rm = TRUE)
# [[1]]
# [1] 3
# 
# [[2]]
# [1] 4

lapply2(list(c(1, 3, 5), c(2, NA, 6)), mean, na.rm = TRUE)
# [[1]]
# [1] 3
# 
# [[2]]
# [1] 4


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow