EDIT: possible au sujet de doublesetnames data.table modification objet dans un environnement appelant
Le proposed link aide à comprendre où la question vient (je l'avais posté déjà comme le 1er commentaire). Cependant, ma question est de savoir comment résoudre le problème spécifique de l'appel de setnames dans une fonction, pas simplement comprendre ce qui se passe, il n'est pas directement abordé là. En utilisant copy
pourrait être une option, il pourrait y avoir d'autres.
La question avait 2 downvotes sans commentaire jusqu'à présent, s'il vous plaît parler si je peux l'améliorer.
data.tables::setnames
modifie des valeurs par référence, dans le cas ci-dessous, il semble conduire à un comportement inattendu (inattendu pour moi au moins).
J'ai trouvé une manière laide de le gérer, mais il y a peut-être une meilleure façon plus systématique d'y aller, alors j'aimerais vos suggestions.
Le comportement étrange
df1 <- data.frame(a=1,b="x")
f1 <- function(df2){
setnames(df2,"b","c")
df2
}
f1(df1)
# a c
# 1 1 x
df1
# a c
# 1 1 x
DF1 a été modifié
si je fais une copie?
df1 <- data.frame(a=1,b="x")
f1 <- function(df2){
df3 <- df2
setnames(df3,"b","c")
df3
}
f1(df1)
# a c
# 1 1 x
df1
# a c
# 1 1 x
Nope
si je fais une copie et "faire semblant de changer", mais ne pas
df1 <- data.frame(a=1,b="x")
f1 <- function(df2){
df3 <- subset(df2) # note: it doesn't work with `identity`, EDIT: we can also use `data.table::copy`
setnames(df3,"b","c")
df3
}
f1(df1)
# a c
# 1 1 x
df1
# a b
# 1 1 x
Il fonctionne
Comment devrait J'y vais? Est-ce un bug?
EDIT: J'ai découvert data.table a une fonction copy
qui est plus général et certainement plus efficace que mon utilisation de subset
Ceci est lié: https://stackoverflow.com/questions/15913417/why-does-data-table-update-namesdt-by-reference-even-if-i-assign-to-another- v –
Je pense que 'copy' est probablement la meilleure solution, mais peut-être que quelqu'un d'autre peut peser. Le' df2' pointe vers le même objet que 'df1' alors quand' setnames' modifie 'df2' c'est vraiment aussi 'df1' (parce que le point de' setnames' est de ne pas faire une copie de l'objet que vous modifiez). Essayez 'library (pryr); adresse (df1); f_address <- fonction (df2) print (adresse (df2)); f_address (df1) ' –
Plus de code de test si vous êtes intéressé -' x <-1; y <- x adresse (x); adresse (y) '. L'utilisation de 'setattr (x," test ", TRUE)' à la fois 'x' et' y' sera changé car 'setattr' est spécifiquement conçu pour ne pas faire de copie. Cependant, en utilisant une approche de base R avec quelque chose comme: 'attributes (y) <- list (" Attr2 "= FALSE)' nous voyons que 'y' et' x' diffèrent maintenant et vérifiant les 'adresse's ils pointent vers différents objets. –