दिलचस्प पोस्ट
जेएक्स-आरएस पोस्ट कई ऑब्जेक्ट्स VM और PyCharm के साथ कस्टम PYTHONPATH को कॉन्फ़िगर कैसे करें? एकाधिक कॉलम से समूह ExecuteScalar, ExecuteReader और ExecuteNonQuery के बीच अंतर क्या है? क्यों अलग सेम प्रबंधन एनोटेशन हैं? एसक्यूएल में एक सूचकांक क्या है? कैसे सी # में iterator के साथ एक पाठ फ़ाइल को पढ़ने के लिए गिट – डेटाबेस में सभी ऑब्जेक्ट्स को कैसे सूचीबद्ध किया जाए JSF परियोजना में <welcome-file> के माध्यम से डिफ़ॉल्ट होम पेज सेट करें एंड्रॉइड में एक HTML लिंक से एक पृष्ठ का html स्रोत कैसे प्राप्त करें? विज़ुअल स्टूडियो संपादक रिक्त स्थान में डॉट्स को क्यों दिखाता है? जावा में एक सूचक और एक संदर्भ चर के बीच अंतर क्या है? नियमित अभिव्यक्ति जो मान्य IPv6 पते से मेल खाता है 2 रेट्रोफ़िट – डायनामिक URL एआरसी के तहत ऑब्जेक्ट के लिए कमजोर संदर्भों (__unsafe_unretained) के एनएसएआरआरए

प्रत्येक पंक्ति से कई तर्कों के साथ डेटाफ्रेम की प्रत्येक पंक्ति पर कॉल लागू-जैसे फ़ंक्शन

मेरे पास कई कॉलम के साथ एक डाटाफ्रेम है डेटाफ्रेम में प्रत्येक पंक्ति के लिए, मैं पंक्ति पर एक फ़ंक्शन कॉल करना चाहता हूं और फ़ंक्शन का इनपुट उस पंक्ति से कई कॉलम का उपयोग कर रहा है। उदाहरण के लिए, मान लीजिए मेरे पास यह डेटा है और यह testFunc जो दो तर्क स्वीकार करता है:

> df <- data.frame(x=c(1,2), y=c(3,4), z=c(5,6)) > df xyz 1 1 3 5 2 2 4 6 > testFunc <- function(a, b) a + b 

मान लीजिए कि मैं इस परीक्षा को लागू करना चाहता हूं। तो, पंक्ति 1 के लिए मुझे 1 + 5 चाहिए और पंक्ति 2 के लिए मुझे 2 + 6 चाहिए। क्या ऐसा करने का कोई तरीका है लूप लिखने के बिना, फ़ंक्शन फ़ैक्टर को लागू करने के साथ?

मैंने यह कोशिश की:

 > df[,c('x','z')] xz 1 1 5 2 2 6 > lapply(df[,c('x','z')], testFunc) Error in a + b : 'b' is missing 

लेकिन किसी भी विचार में त्रुटि मिली?

संपादित करें: वास्तविक फ़ंक्शन जिसे मैं कॉल करना चाहता हूँ वह एक सरल राशि नहीं है, लेकिन यह power.t.test है मैंने सिर्फ उदाहरण के उद्देश्यों के लिए एक + बी का उपयोग किया था अंतिम लक्ष्य इस तरह कुछ करने में सक्षम होना है (छद्मोकोड में लिखा गया है):

 df = data.frame( delta=c(delta_values), power=c(power_values), sig.level=c(sig.level_values) ) lapply(df, power.t.test(delta_from_each_row_of_df, power_from_each_row_of_df, sig.level_from_each_row_of_df )) 

जहां परिणाम डीएफ के प्रत्येक पंक्ति के लिए power.t.test के लिए आउटपुट का एक सदिश है।

वेब के समाधान से एकत्रित समाधान "प्रत्येक पंक्ति से कई तर्कों के साथ डेटाफ्रेम की प्रत्येक पंक्ति पर कॉल लागू-जैसे फ़ंक्शन"

आप मूल डेटा के सबसेट पर लागू apply कर सकते हैं।

  dat <- data.frame(x=c(1,2), y=c(3,4), z=c(5,6)) apply(dat[,c('x','z')], 1, function(x) sum(x) ) 

या यदि आपका फ़ंक्शन केवल वेक्टरयुक्त संस्करण का योग है:

 rowSums(dat[,c('x','z')]) [1] 6 8 

यदि आप testFunc का उपयोग करना चाहते हैं

  testFunc <- function(a, b) a + b apply(dat[,c('x','z')], 1, function(x) testFunc(x[1],x[2])) 

संपादित करें नाम के आधार पर स्तंभों तक पहुंचने के लिए और आप ऐसा कुछ कर सकते हैं:

  testFunc <- function(a, b) a + b apply(dat[,c('x','z')], 1, function(y) testFunc(y['z'],y['x'])) 

एक data.frame एक list , इसलिए …

do.call लिए आमतौर पर do.call आमतौर पर एक अच्छा शर्त है लेकिन तर्कों के नाम खेलने में आते हैं यहां आपके testFunc को testFunc और एक्स के स्थान पर testFunc एक्स और वाई के साथ कहा जाता है। ... एक त्रुटि के बिना अप्रासंगिक तर्क को पारित करने की अनुमति देता है:

 do.call( function(x,z,...) testFunc(x,z), df ) 

गैर- mapply कार्यों के लिए , mapply काम करेगी, लेकिन आपको mapply के ऑर्डर से मिलान करना होगा या उन्हें स्पष्ट रूप से नाम देना होगा:

 mapply(testFunc, df$x, df$z) 

कभी-कभी apply हैं – जैसे कि सभी data.frame एक ही प्रकार के होते हैं, इसलिए data.frame को data.frame लिए मैट्रिक्स में डेटा प्रकार बदलकर समस्याएं पैदा नहीं होती हैं। आपका उदाहरण इस प्रकार का था

यदि आपके फ़ंक्शन को किसी अन्य फ़ंक्शन के भीतर बुलाया जाना है जिसमें तर्क सभी पारित किए जाते हैं, तो इन की तुलना में एक बहुत अधिक मज़ेदार विधि है। यदि आप उस मार्ग पर जाना चाहते हैं तो lm() के शरीर की पहली पंक्ति का अध्ययन करें

mapply उपयोग करें

 > df <- data.frame(x=c(1,2), y=c(3,4), z=c(5,6)) > df xyz 1 1 3 5 2 2 4 6 > mapply(function(x,y) x+y, df$x, df$z) [1] 6 8 > cbind(df,f = mapply(function(x,y) x+y, df$x, df$z) ) xyzf 1 1 3 5 6 2 2 4 6 8 

dplyr पैकेज के साथ नया जवाब

यदि फ़ंक्शन जिसे आप लागू करना चाहते हैं तो dplyr , तो आप dplyr पैकेज से mutate फ़ंक्शन का उपयोग कर सकते हैं:

 > library(dplyr) > myf <- function(tens, ones) { 10 * tens + ones } > x <- data.frame(hundreds = 7:9, tens = 1:3, ones = 4:6) > mutate(x, value = myf(tens, ones)) hundreds tens ones value 1 7 1 4 14 2 8 2 5 25 3 9 3 6 36 

plyr पैकेज के साथ पुराने उत्तर

मेरी विनम्र राय में, काम करने के लिए सबसे उपयुक्त टूल plyr पैकेज से plyr है

उदाहरण:

 > library(plyr) > x <- data.frame(tens = 1:3, ones = 4:6) > mdply(x, function(tens, ones) { 10 * tens + ones }) tens ones V1 1 1 4 14 2 2 5 25 3 3 6 36 

दुर्भाग्य से, बर्टजन ब्रोकेसिमा ने बताया, यदि आप डेटा फ़्रेम के सभी कॉलम mdply कॉल में उपयोग नहीं करते हैं तो यह दृष्टिकोण विफल हो जाता है। उदाहरण के लिए,

 > library(plyr) > x <- data.frame(hundreds = 7:9, tens = 1:3, ones = 4:6) > mdply(x, function(tens, ones) { 10 * tens + ones }) Error in (function (tens, ones) : unused argument (hundreds = 7) 

कई कार्य पहले से ही सदिश हैं, और इसलिए किसी भी पुनरावृत्त की आवश्यकता नहीं है (न ही लूप या *pply फ़ंक्शन के लिए) आपका testFunc एक ऐसा उदाहरण है। आप बस कॉल कर सकते हैं:

  testFunc(df[, "x"], df[, "z"]) 

सामान्य तौर पर, मैं पहले इस तरह के सदिशीकरण के प्रयासों की कोशिश करूँगा और देखेंगे कि क्या आपको अपने इच्छित परिणाम मिलेंगे।


वैकल्पिक रूप से, यदि आपको किसी फ़ंक्शन पर कई तर्कों को पारित करने की आवश्यकता होती है जो mapply नहीं है, mapply हो सकता है कि आप क्या चाहते हैं:

  mapply(power.t.test, df[, "x"], df[, "z"]) 

दूसरों ने सही ढंग से बताया है कि इस उद्देश्य के लिए mapply बनाया गया है, लेकिन (पूर्णता के लिए) एक सरल तरीके से सरल तरीका सिर्फ एक लूप का उपयोग for है।

 for (row in 1:nrow(df)) { df$newvar[row] <- testFunc(df$x[row], df$z[row]) } 

यहाँ एक वैकल्पिक दृष्टिकोण है यह अधिक सहज है

एक महत्वपूर्ण पहलू मुझे लगता है कि कुछ जवाबों को ध्यान में नहीं रखा है, जिसे मैं भावी पीढ़ी के लिए बताता हूं, आवेदन करता है () आपको आसानी से पंक्ति गणना करता है, लेकिन केवल मैट्रिक्स (सभी संख्यात्मक) डेटा के लिए

कॉलम पर कार्रवाई डेटाफ़्रेम के लिए अभी भी संभव है:

 as.data.frame(lapply(df, myFunctionForColumn())) 

पंक्तियों पर काम करने के लिए, हम पहले स्थानांतरित कर देते हैं।

 tdf<-as.data.frame(t(df)) as.data.frame(lapply(tdf, myFunctionForRow())) 

नकारात्मक पक्ष यह है कि मेरा मानना ​​है कि आर आपके डेटा तालिका की एक प्रतिलिपि बना देगा। जो एक स्मृति मुद्दा हो सकता है (यह सचमुच दुखी है, क्योंकि यह प्रोग्राम के लिए सरल है, सिर्फ मूल डीएफ के लिए एक इटरेटर होने के लिए tdf, इस प्रकार स्मृति को बचाया जा रहा है, लेकिन आर सूचक को संदर्भित करने वाला या इरेटरेटर को संदर्भित नहीं करता है।)

इसके अलावा, एक संबंधित प्रश्न यह है कि डेटाफ्रेम में प्रत्येक व्यक्तिगत सेल पर कैसे काम किया जाए।

 newdf <- as.data.frame(lapply(df, function(x) {sapply(x, myFunctionForEachCell()})) 

मैं यहां आया था tidyverse फ़ंक्शन नाम – जिसे मैं जानता था कि अस्तित्व में है। (मेरे) भविष्य के संदर्भ और निडर उत्साही लोगों के लिए इसे जोड़ना: purrr:invoke_rows

मूल प्रश्नों के अनुसार मानक आँकड़े के तरीकों से जुड़े होने के कारण, ब्रूम पैकेज संभवतः मदद करेगा

@ उपयोगकर्ता 20877984 का उत्तर उत्कृष्ट है। चूंकि वे इसे मेरे पिछले उत्तर की तुलना में कहीं ज्यादा बेहतर समझाते हैं, इसलिए ये मेरा (posibly अभी भी घटिया) अवधारणा के आवेदन पर प्रयास है:

एक बुनियादी फैशन में do.call का उपयोग करना:

 powvalues <- list(power=0.9,delta=2) do.call(power.t.test,powvalues) 

पूर्ण डेटा सेट पर काम करना:

 # get the example data df <- data.frame(delta=c(1,1,2,2), power=c(.90,.85,.75,.45)) #> df # delta power #1 1 0.90 #2 1 0.85 #3 2 0.75 #4 2 0.45 

निर्दिष्ट मानों की प्रत्येक lapply में power.t.test

 result <- lapply( split(df,1:nrow(df)), function(x) do.call(power.t.test,x) ) > str(result) List of 4 $ 1:List of 8 ..$ n : num 22 ..$ delta : num 1 ..$ sd : num 1 ..$ sig.level : num 0.05 ..$ power : num 0.9 ..$ alternative: chr "two.sided" ..$ note : chr "n is number in *each* group" ..$ method : chr "Two-sample t test power calculation" ..- attr(*, "class")= chr "power.htest" $ 2:List of 8 ..$ n : num 19 ..$ delta : num 1 ..$ sd : num 1 ..$ sig.level : num 0.05 ..$ power : num 0.85 ... ... 

यदि data.frame कॉलम भिन्न प्रकार हैं, तो apply() में कोई समस्या है। पंक्ति चलना के बारे में एक सूक्ष्मता है कि कैसे apply(a.data.frame, 1, ...) वर्ण प्रकारों में अंतर्निहित प्रकार रूपांतरण करता है जब स्तंभ भिन्न प्रकार होते हैं; जैसे। एक कारक और संख्यात्मक स्तंभ यहां एक उदाहरण है, एक संख्यात्मक स्तंभ को संशोधित करने के लिए एक स्तंभ में एक कारक का उपयोग करना:

 mean.height = list(BOY=69.5, GIRL=64.0) subjects = data.frame(gender = factor(c("BOY", "GIRL", "GIRL", "BOY")) , height = c(71.0, 59.3, 62.1, 62.1)) apply(height, 1, function(x) x[2] - mean.height[[x[1]]]) 

घटाव विफल हो जाता है क्योंकि कॉलम वर्ण प्रकारों में कनवर्ट किए जाते हैं।

एक फिक्स दूसरे कॉलम को किसी संख्या में वापस-कनवर्ट करना है:

 apply(subjects, 1, function(x) as.numeric(x[2]) - mean.height[[x[1]]]) 

लेकिन रूपांतरण को कॉलम्स अलग रखने और mapply() का उपयोग करने से बचाया जा सकता है:

 mapply(function(x,y) y - mean.height[[x]], subjects$gender, subjects$height) 

mapply() की आवश्यकता है क्योंकि [[ ]] वेक्टर तर्क को स्वीकार नहीं करता है। इसलिए कॉलम फ़िसरना एक वेक्टर को [] थोड़ा अधिक बदसूरत कोड करके, घटाव से पहले किया जा सकता है:

 subjects$height - unlist(mean.height[subjects$gender])