2011-11-21 12 views
48

में मानों का सशर्त प्रतिस्थापन मैं समझने की कोशिश कर रहा हूं कि एक लूप का उपयोग किए बिना डेटाफ्रेम में सशर्त को कैसे सशर्त करना है। मेरे डेटा फ्रेम इस प्रकार संरचित है:डेटा.फ्रेम

> df 
      a b est 
1 11.77000 2 0 
2 10.90000 3 0 
3 10.32000 2 0 
4 10.96000 0 0 
5 9.90600 0 0 
6 10.70000 0 0 
7 11.43000 1 0 
8 11.41000 2 0 
9 10.48512 4 0 
10 11.19000 0 0 

और dput उत्पादन यह है:

structure(list(a = c(11.77, 10.9, 10.32, 10.96, 9.906, 10.7, 
11.43, 11.41, 10.48512, 11.19), b = c(2, 3, 2, 0, 0, 0, 1, 2, 
4, 0), est = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), .Names = c("a", 
"b", "est"), row.names = c(NA, -10L), class = "data.frame") 

मैं आपकी क्या अपेक्षाएं हैं, b के मान की जाँच करने के लिए है। यदि b 0 है, तो को a से मान के लिए सेट करना चाहता हूं। मैं समझता हूं कि df$est[df$b == 0] <- 23est से 23 के सभी मान सेट करेगा, जब b==0। मुझे समझ में नहीं आता है कि esta के मान पर सेट करने के लिए यह स्थिति कब सही है। उदाहरण के लिए:

Warning message: 
In df$est[df$b == 0] <- (df$a - 5)/2.533 : 
    number of items to replace is not a multiple of replacement length 

वहाँ एक रास्ता है कि मैं नहीं बल्कि वेक्टर से, प्रासंगिक सेल पारित कर सकते हैं है:

df$est[df$b == 0] <- (df$a - 5)/2.533 

निम्नलिखित चेतावनी देता है?

उत्तर

53

जब से तुम सशर्त df$est का अनुक्रमण कर रहे हैं, आप भी सशर्त सूचकांक प्रतिस्थापन सदिश df$a की जरूरत है:

index <- df$b == 0 
df$est[index] <- (df$a[index] - 5)/2.533 
बेशक

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

df$est[df$b == 0] <- (df$a[df$b == 0] - 5)/2.533 

भी बेहतर readibility के लिए, आप उपयोग कर सकते हैं within:

df <- within(df, est[b==0] <- (a[b==0]-5)/2.533) 

परिणाम, चाहे कोई भी विधि का आपके द्वारा चुने गए:

df 
      a b  est 
1 11.77000 2 0.000000 
2 10.90000 3 0.000000 
3 10.32000 2 0.000000 
4 10.96000 0 2.352941 
5 9.90600 0 1.936834 
6 10.70000 0 2.250296 
7 11.43000 1 0.000000 
8 11.41000 2 0.000000 
9 10.48512 4 0.000000 
10 11.19000 0 2.443743 

जैसा कि अन्य ने बताया है, आपके उदाहरण में एक वैकल्पिक समाधान ifelse का उपयोग करना है ।

11

यहां एक दृष्टिकोण है। ifelse वेक्टरकृत है और यह b के शून्य मानों के लिए सभी पंक्तियों की जांच करता है और est(a - 5)/2.53 के साथ बदलता है यदि ऐसा है।

df <- transform(df, est = ifelse(b == 0, (a - 5)/2.53, est)) 
5

R-inferno, या मूल आर-दस्तावेज बताएगा कि डीएफ $ * का उपयोग क्यों करना सबसे अच्छा तरीका नहीं है। सहायता पृष्ठ से "[":

"इंडेक्सिंग [परमाणु वैक्टर के समान है और निर्दिष्ट तत्वों की एक सूची का चयन करता है। दोनों [[और $ सूची का एक तत्व चुनें। मुख्य अंतर यह है कि $ गणना किए गए सूचकांक की अनुमति नहीं देता है, जबकि [[x। x $ नाम x [["name", सटीक = गलत]] के बराबर है। इसके अलावा, आंशिक मिलान व्यवहार [[सटीक तर्क का उपयोग करके नियंत्रित किया जा सकता है "

मैं इसके बजाय [row,col] नोटेशन का उपयोग करने की सलाह देता हूं।उदाहरण:

Rgames: foo 
     x y z 
    [1,] 1e+00 1 0 
    [2,] 2e+00 2 0 
    [3,] 3e+00 1 0 
    [4,] 4e+00 2 0 
    [5,] 5e+00 1 0 
    [6,] 6e+00 2 0 
    [7,] 7e+00 1 0 
    [8,] 8e+00 2 0 
    [9,] 9e+00 1 0 
    [10,] 1e+01 2 0 
Rgames: foo<-as.data.frame(foo) 

Rgames: foo[foo$y==2,3]<-foo[foo$y==2,1] 
Rgames: foo 
     x y  z 
1 1e+00 1 0e+00 
2 2e+00 2 2e+00 
3 3e+00 1 0e+00 
4 4e+00 2 4e+00 
5 5e+00 1 0e+00 
6 6e+00 2 6e+00 
7 7e+00 1 0e+00 
8 8e+00 2 8e+00 
9 9e+00 1 0e+00 
10 1e+01 2 1e+01 
+0

यह एक वोट दें हकदार अगर आप पहले आर इन्फर्नो पेज के लिए या तो एक लिंक जोड़ने , या '$ '(या आदर्श दोनों) के साथ मुद्दों को सारांशित करें। – Andrie

+0

+1 हालांकि मुझे लगता है कि इस मामले में '$' ऑपरेटर पूरी तरह ठीक है। (साथ ही, मुझे लगता है कि आपकी चेतावनी के बावजूद आप '$' स्वयं का उपयोग करते हैं ...) – Andrie

+0

@Andrie: हाँ, मैंने इसे इस्तेमाल किया जहां यह काम करता है (ऐसा नहीं है कि यह बहुत मदद है :-))। ओपी ने यह परिभाषित करने की कोशिश की कि किस तत्व पर कार्य किया जा रहा है, जहां समस्या शुरू हुई थी। मैंने बस उस स्थिति को परिभाषित करने के लिए उपयोग किया जो डेटाफ्रेम तत्वों का चयन करता है। लेकिन आप जानते थे कि :-) –

24

कोशिश data.table के := ऑपरेटर:

DT = as.data.table(df) 
DT[b==0, est := (a-5)/2.533] 

यह तेजी से और कम है। := बारे में अधिक जानकारी के लिए इन लिंक किए गए प्रश्न देखें:

Why has data.table defined :=

When should I use the := operator in data.table

How do you remove columns from a data.frame

R self reference

+0

सुंदर, सब कुछ के लिए संदर्भ +1 के लिए धन्यवाद। – PKumar

+0

बहुत उपयोगी प्रतिक्रिया। यदि आप इसका उपयोग करते हैं, तो यह सुनिश्चित करना सुनिश्चित करें कि डीटी डेटा.table पैकेज में कोई फ़ंक्शन नहीं है, लेकिन डेटा तालिका ऑब्जेक्ट का संदर्भ है। –

संबंधित मुद्दे