2014-05-02 12 views
21

निम्नलिखित पर विचार करें:अंतर (df [1]) <- -` और `नाम (DF) [1] <`

df <- data.frame(a = 1, b = 2, c = 3) 
names(df[1]) <- "d" ## First method 
## a b c 
##1 1 2 3 

names(df)[1] <- "d" ## Second method 
## d b c 
##1 1 2 3 

दोनों ही तरीकों से एक त्रुटि वापस नहीं किया था, लेकिन पहले कॉलम नाम नहीं बदला, जबकि दूसरा किया।

मैंने सोचा कि इसमें इस तथ्य के साथ कुछ करना है कि मैं केवल df के उप-समूह पर काम कर रहा हूं, लेकिन उदाहरण के लिए, निम्नलिखित ठीक काम क्यों करते हैं?

df[1] <- 2 
## a b c 
##1 2 2 3 
+1

मुझे यहां यहोशू का जवाब पसंद है: http://stackoverflow.com/a/10449502/1270695। वह कहता है कि यह जादू है। – A5C1D2H2I1M1N2O1R2T1

+0

यहोशू का जवाब दूसरे उदाहरण को संदर्भित करता है, जिसने कुछ भी नहीं किया है ... –

+2

ओहॉयबॉयबॉय, क्या आप एक इलाज के लिए हैं: इस मशहूर मोनोग्राफ को पढ़ें (http) //www.burns-stat .com/पेज/ट्यूटर/R_inferno.pdf –

उत्तर

26

क्या मुझे लगता है कि क्या हो रहा है एक डेटा फ्रेम में है कि प्रतिस्थापन कि से ली गई है डेटा फ्रेम की विशेषताओं पर ध्यान नहीं देता है। मैं 100% इस बारे में सुनिश्चित नहीं हूँ, लेकिन निम्न प्रयोगों यह बैकअप लेने के लिए दिखाई देते हैं:

df <- data.frame(a = 1:3, b = 5:7) 
# a b 
# 1 1 5 
# 2 2 6 
# 3 3 7 

df2 <- data.frame(c = 10:12) 
# c 
# 1 10 
# 2 11 
# 3 12 

df[1] <- df2[1] # in this case `df[1] <- df2` is equivalent 

कौन सा पैदा करता है:

# a b 
# 1 10 5 
# 2 11 6 
# 3 12 7 

सूचना कैसे मान df के लिए बदल गया है, लेकिन नहीं के नाम। असल में प्रतिस्थापन ऑपरेटर `[<-` केवल मानों को प्रतिस्थापित करता है। यही कारण है कि नाम अद्यतन नहीं किया गया था। मेरा मानना ​​है कि यह सभी मुद्दों को बताता है।

परिदृश्य में:

names(df[2]) <- "x" 

आप काम के बारे में सोच सकते हैं इस प्रकार है (यह एक सरलीकरण है, और अधिक विस्तार के लिए पोस्ट के अंत देखें):

tmp <- df[2] 
# b 
# 1 5 
# 2 6 
# 3 7 

names(tmp) <- "x" 
# x 
# 1 5 
# 2 6 
# 3 7 

df[2] <- tmp # `tmp` has "x" for names, but it is ignored! 
# a b 
# 1 10 5 
# 2 11 6 
# 3 12 7 

अंतिम चरण जिनमें से `[<-` के साथ एक असाइनमेंट है, जो आरएचएस के नाम गुणों का सम्मान नहीं करता है।

लेकिन परिदृश्य में:

names(df)[2] <- "x" 

आप के रूप में काम (फिर से, एक सरलीकरण) के बारे में सोच सकते हैं:

tmp <- names(df) 
# [1] "a" "b" 

tmp[2] <- "x" 
# [1] "a" "x" 

names(df) <- tmp 
# a x 
# 1 10 5 
# 2 11 6 
# 3 12 7 

सूचना कैसे हम सीधे, names को असाइन बजाय df को देने की जो गुणों को अनदेखा करता है।

df[2] <- 2 

काम करता है क्योंकि हम सीधे मूल्यों को आवंटित कर रहे हैं, विशेषताओं में नहीं, इसलिए यहां कोई समस्या नहीं है।


संपादित करें: @ AriB.Friedman से कुछ टिप्पणी के आधार पर, यहाँ मैं क्या सोचता हूँ पर जा रहा है की एक अधिक विस्तृत संस्करण है (ध्यान दें मैं `[.data.frame` को S3 प्रेषण को छोड़ते हुए हूँ, आदि, स्पष्टता) के लिए:

संस्करण 1 names(df[2]) <- "x" तब्दील करने के लिए:

df <- `[<-`(
    df, 2, 
    value=`names<-`( # `names<-` here returns a re-named one column data frame 
    `[`(df, 2),  
    value="x" 
)) 

संस्करण 2 names(df)[2] <- "x" तब्दील करने के लिए:

df <- `names<-`(
    df, 
    `[<-`(
    names(df), 2, "x" 
)) 

इसके अलावा, पता चला है कि यह "दस्तावेज" है आर इन्फर्नो में धारा 8.2.34 (धन्यवाद @ फ्रैंक):

right <- wrong <- c(a=1, b=2) 
names(wrong[1]) <- 'changed' 
wrong 
# a b 
# 1 2 
names(right)[1] <- 'changed' 
right 
# changed b 
# 1 2 
संबंधित मुद्दे