je comprends toujours ce grand paquet ... Quelqu'un pourrait-il s'il vous plaît m'expliquer la raison de cette erreur? Merci!
library(data.table)
DT <- data.table(id = LETTERS,
var1 = rnorm(26),
var2 = rnorm(26))
> DT[2, list(var1, var2)]
var1 var2
1: -0.8628479332 -0.2367492928
> DT[2, c(var1, var2)]
[1] -0.8628479332 -0.2367492928
>
> DT[2, list(var1, var2)] <- DT[8, list(var1, var2)]
Error in `[<-.data.table`(`*tmp*`, 2, list(var1, var2), value = list(var1 = -0.394006912428776, :
object 'var1' not found
> DT[2, c(var1, var2)] <- DT[8, c(var1, var2)]
Error in `[<-.data.table`(`*tmp*`, 2, c(var1, var2), value = c(-0.394006912428776, :
object 'var1' not found
Tout d'abord, il est recommandé d'utiliser :=
Au lieu de [<-
Pour plus d'efficacité. Le [<-
Est principalement fourni pour la cohérence descendante. Donc, je vais d'abord illustrer comment utiliser efficacement :=
Pour obtenir ce que vous recherchez. :=
Est une affectation par référence (et il met à jour une data.table sans copier les données, donc extrêmement rapidement).
require(data.table)
DT <- data.table(x = 1:5, y = 6:10, z = 11:15)
Supposons que vous souhaitiez remplacer la 2ème ligne de "y" par celle de la 5ème ligne de "y":
DT[2, y := DT[5, y]]
ou équivalent
DT[2, `:=`(y = DT[5, y])]
Supposons que vous souhaitiez remplacer la deuxième ligne de les deux "y" et "z" par celle des entrées correspondantes de la ligne 5, puis:
DT[2, c("y", "z") := as.list(DT[5, c(y, z)])]
ou équivalent
DT[2, `:=`(y = DT[5, y], z = DT[5, z])]
Maintenant, juste pour vous montrer comment attribuer en utilisant [<-
(Bien que ce ne soit clairement pas recommandé), cela peut être fait comme suit:
DT <- data.table(x = 1:5, y = 6:10, z = 11:15)
DT[1, c("y", "z")] <- as.list(DT[5, c(y, z)])
ou de manière équivalente, vous pouvez également transmettre le numéro de colonne:
DT[1, 2:3] <- as.list(DT[5, c(y, z)])
J'espère que cela t'aides.
Tout d'abord, le RHS doit être une liste pour [<-data.table
S'il a plus de 1 colonnes à affecter.
Deuxièmement, l'argument j
à gauche de <-
N'est pas évalué dans l'environnement de votre data.table. Il a donc besoin de savoir quelles sont les valeurs de j
. Et puisque vous fournissez var1
Et var2
(sans les guillemets qui en feraient un vecteur de caractères), il est compris comme une variable. Et donc, il vérifie les variables var1
Et var2
, Mais comme il ne "voit" pas les colonnes de votre data.table comme des variables (comme il le fait normalement lorsque vous faites des affectations, etc. le RHS de <-
), il cherchera les mêmes variables dans son environnement parent qui est l'environnement global où il ne les trouve pas et ainsi vous obtenez l'erreur. Par exemple: faites ceci:
y <- "y"
z <- "z"
# And now try your second case:
DT[2, c(y, z)] <- as.list(DT[5, c(y, z)])
# the left side takes values from the assignments you made above
# the right side y and z are evaluated within the environment of your data.table
# and so it sees the columns y and z as variables and their values are picked accordingly
Troisièmement, la fonction [<-data.table
N'accepte que les types atomic
(vecteur) pour l'argument j
. Ainsi, votre première affectation DT[2, list(var1, var2)] <- DT[8, list(var1, var2)]
donnera toujours une erreur si vous le faites correctement, c'est-à-dire:
y <- "y"
z <- "z"
DT[2, list(y, z)] <- as.list(DT[5, c(y, z)])
# Error in `[<-.data.table`(`*tmp*`, 2, list(y, z), value = list(10L, 15L)) :
# j must be atomic vector, see ?is.atomic
j'espère que cela t'aides.
[<-
Mais pas lorsque :=
,DT <- data.table(x = 1:5, y = 6:10, z = 11:15)
tracemem(DT)
# [1] "<0x7fbefb89b580>"
DT[1, c("y", "z") := list(100L, 110L)]
tracemem(DT)
# [1] "<0x7fbefb89b580>"
DT[2, c("y", "z")] <- list(200L, 201L)
# tracemem[0x7fbefacc4fa0 -> 0x7fbefd297838]: # copied, inefficient