2011-05-23 11 views
6

उम्मीद है कि यह एक बहुत ही मूर्ख सवाल नहीं है, लेकिन अभी भी एक आर शुरुआती होने के नाते मुझे झटके से गंभीर समस्या है।मूल्यों का क्रम कैसे उपयोग करें और संरक्षित करें

c(1,2,3,4,5,NA,7,0,NA) 

में बहुत धन्यवाद: कहते हैं कि चलो

factors <- as.factor(c("a", "b", "c", "a", "b", "c", "a", "b", "c")) 
values <- c(1, 2, 3, 4, 5, NA, 7, NA, NA) 
tapply(
    values, 
    factors, 
    function(x){ 
    if(sum(is.na(x)) == 1){ 
     x[ is.na(x) ] <- 0 
    } 
    return(x) 
    } 
) 

परिणाम

$a 
[1] 1 4 7 

$b 
[1] 2 5 0 

$c 
[1] 3 NA NA 

हालांकि है, मैं क्या जरूरत है एक वेक्टर वापस जो मूल्यों के मूल आदेश को बरकरार रखता है, यानी प्राप्त करने के लिए है अग्रिम।

+0

यह स्टैक ओवरफ्लो पर मेरा पहला प्रश्न था और मैं तेज़ एच के बारे में बहुत प्रभावित हूं मुझे मिल गया सभी को बहुत धन्यवाद। – Beasterfield

+4

ऐसा इसलिए है क्योंकि आपका प्रश्न स्पष्ट है, जिसमें सभी प्रासंगिक जानकारी और डेटा शामिल हैं। – Marek

उत्तर

7

उस मामले में आप ave समारोह का उपयोग करना चाहिए:

> ave(values, factors, FUN=function(x) { 
+  if(sum(is.na(x)) == 1){ 
+  x[ is.na(x) ] <- 0 
+  } 
+  return(x) 
+ } 
+) 
[1] 1 2 3 4 5 NA 7 0 NA 
+0

इससे बहुत मदद मिली, धन्यवाद! – Beasterfield

+1

हाँ। एवी समारोह बहुत अच्छा है। आपको बस स्पष्ट रूप से उपयोग करने की याद रखने की आवश्यकता है ... FUN = –

+0

सच है, मुझे पता लगाने में कुछ मिनट लग गए। लेकिन फिर भी आपने वास्तव में मुझे अपने उत्तर से खुश कर दिया। – Beasterfield

1

एक साधारण for पाश यह बहुत ही बस करता है:

fun <- function(x){ 
    if(sum(is.na(x)) == 1){x[is.na(x)] <- 0} 
     return(x) 
} 

for (i in unique(factors)){ 
    values[i == factors] <- fun(values[i == factors]) 
} 
+0

मैंने इसके बारे में भी सोचा। लेकिन क्या ये सभी लागू-कार्य समय लूप के साथ मैन्युअल रूप से डेटा पर फिर से शुरू करने से अधिक तेज़ नहीं हैं? विशेष रूप से कम्प्यूटेशनल मांग मेरे डेटा के लिए एक मुद्दा है। – Beasterfield

+0

हमेशा नहीं, tapply और लागू सिर्फ वाक्य रचनात्मक चीनी हैं। कंसोल में tapply() प्रकार 'tapply' के लिए स्रोत देखें। मुझे लगता है कि बिंदु वास्तव में है कि प्रत्येक में डेटा की लंबाई की तुलना में पुनरावृत्तियों की संख्या छोटी (आमतौर पर) होने जा रही है। – mdsumner

+0

मैं mdsumner से सहमत हूं, हालांकि इस मामले में मेरा मानना ​​है कि 'एवी()' का उपयोग कर डीविन का जवाब लूप के लिए स्पष्ट रूप से काफी तेज़ है। – joran

0

एक विकल्प विभाजन के लिए प्रतिस्थापन विधि() का उपयोग करने के लिए है:

## create a copy to store the result after replacement 
res <- values 

## use split's replacement method to split, apply, and recombine 
split(res, factors) <- lapply(split(res, factors), 
function(x){ 
if(sum(is.na(x)) == 1){ 
    x[ is.na(x) ] <- 0 
} 
    return(x) 
} 
) 
संबंधित मुद्दे