Quello che penso sta accadendo è che la sostituzione in una cornice di dati ignora gli attributi del frame di dati che è tratto da. Io non sono sicuro al 100% di questo, ma i seguenti esperimenti apparire una copia di backup:
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
che produce:
# a b
# 1 10 5
# 2 11 6
# 3 12 7
notare come i valori modificati per df
, ma non i nomi. Fondamentalmente l'operatore sostitutivo `[<-`
sostituisce solo i valori. Questo è il motivo per cui il nome non è stato aggiornato. Credo che questo spieghi tutti i problemi.
Nello scenario:
names(df[2]) <- "x"
si può pensare l'assegnazione come segue (questa è una semplificazione, vedi fine del post per maggiori dettagli):
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
L'ultimo passo di cui è un compito con `[<-`
, che non rispetta l'attributo dei nomi del RHS.
Ma nello scenario:
names(df)[2] <- "x"
si può pensare l'assegnazione come (ancora una volta, una semplificazione):
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
Notate come abbiamo direttamente assegniamo a names
, invece di assegnare a df
che ignora gli attributi.
df[2] <- 2
opere perché stiamo assegnando direttamente ai valori, non i attributi, quindi non ci sono problemi qui.
EDIT: sulla base di alcuni commenti da @ AriB.Friedman, qui è una versione più elaborata di quello che penso sta succedendo (nota sto omettendo l'invio S3 per `[.data.frame`
, etc., Per chiarezza):
Versione 1 names(df[2]) <- "x"
traduce:
df <- `[<-`(
df, 2,
value=`names<-`( # `names<-` here returns a re-named one column data frame
`[`(df, 2),
value="x"
))
versione 2 names(df)[2] <- "x"
traduce:
df <- `names<-`(
df,
`[<-`(
names(df), 2, "x"
))
Inoltre, risulta questa è "documentato" in R Inferno Sezione 8.2.34 (Grazie @ Frog):
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
Mi piace la risposta di Joshua qui: http://stackoverflow.com/a/10449502/1270695. Dice che è magico. – A5C1D2H2I1M1N2O1R2T1
La risposta di Giosuè si riferisce al secondo esempio, non a quello che non ha fatto nulla ... –
Ohboyohboy, sei qui per un regalo: leggi questa (in) famosa monografia - http: //www.burns-stat .com/pages/Tutor/R_inferno.pdf –