Deux façons de sélectionner par programme des variables:
with = FALSE
:
DT = data.table(col1 = 1:3)
colname = "col1"
DT[, colname, with = FALSE]
..
Préfixe 'dot dot' ( ):
DT[, ..colname]
Pour une description plus détaillée de la ..
notation «point point» ( ), voir Nouvelles fonctionnalités de la 1.10.2 (elle n'est actuellement pas décrite dans le texte d'aide).
Pour attribuer une ou plusieurs variables, placez la LHS de :=
entre parenthèses:
DT[, (colname) := 4:6]
Ce dernier est connu sous le nom de plonk de colonne , car vous remplacez le vecteur de colonne entier par référence. Si un sous-ensemble i
était présent, il se sous-attribuerait par référence. Le parens autour (colname)
est un raccourci introduit dans la version v1.9.4 sur CRAN octobre 2014. Voici la nouvelle :
L'utilisation de with = FALSE
with :=
est désormais déconseillée dans tous les cas, étant donné que l'encapsulation de la LHS de :=
avec des parenthèses est préférée depuis un certain temps.
colVar = "col1"
DT[, (colVar) := 1]
DT[, c("col1", "col2") := 1]
DT[, 2:4 := 1]
DT[, c("col1","col2") := list(sum(a), mean(b))]
DT[, `:=`(...), by = ...]
Voir également la section Détails dans ?`:=`
:
DT[i, (colnamevector) := value]
Et pour répondre à une autre question en commentaire, voici une façon (comme d'habitude, il y a plusieurs façons):
DT[, colname := cumsum(get(colname)), with = FALSE]
ou, vous pourriez trouver plus facile de lire, d'écrire et de déboguer juste à eval
un paste
, similaire à la construction d'une instruction SQL dynamique à envoyer à un serveur:
expr = paste0("DT[,",colname,":=cumsum(",colname,")]")
expr
eval(parse(text=expr))
Si vous faites beaucoup cela, vous pouvez définir une fonction d'assistance EVAL
:
EVAL = function(...)eval(parse(text=paste0(...)),envir=parent.frame(2))
EVAL("DT[,",colname,":=cumsum(",colname,")]")
Maintenant que la data.table
1.8.2 optimise automatiquement l' j
efficacité, il peut être préférable d'utiliser la eval
méthode. Le get()
in j
empêche certaines optimisations, par exemple.
Ou, il y en a set()
. Une forme fonctionnelle de faible frais généraux, :=
qui conviendrait ici. Voir ?set
.
set(DT, j = colname, value = cumsum(DT[[colname]]))
DT
.
, ou..
d'éviter tout masquage potentiel siDT
jamais il contenait ce symbole comme nom de colonne à l'avenir (et respectez la convention par laquelle les noms de colonne ne commencent pas.
). Il y a quelques demandes de fonctionnalités pour le rendre plus robuste aux problèmes de portée comme celui-ci, tels que l'ajout.()
et..()
.fn$
partir du package gsubfn pour améliorer la lisibilité de la solution EVAL:library(gsubfn); fn$EVAL( "DT[,$colname:=cumsum($colname)]" )
.* Ce n'est pas vraiment une réponse, mais je n'ai pas assez de street cred pour poster des commentaires: /
Quoi qu'il en soit, pour tous ceux qui cherchent à créer une nouvelle colonne dans une table de données avec un nom stocké dans une variable, j'ai ce qui suit pour fonctionner. Je n'ai aucune idée de ses performances. Des suggestions d'amélioration? Est-il prudent de supposer qu'une nouvelle colonne sans nom recevra toujours le nom V1?
colname <- as.name("users") # Google Analytics query is run with chosen metric and resulting data is assigned to DT DT2 <- DT[, sum(eval(colname, .SD)), by = country] setnames(DT2, "V1", as.character(colname))
Remarquez que je peux le référencer très bien dans sum () mais je n'arrive pas à le faire attribuer dans la même étape. BTW, la raison pour laquelle je dois le faire est que colname sera basé sur l'entrée de l'utilisateur dans une application Shiny.
la source
V1
c'est le nouveau nom. Par exemple, si vous lisez csv avecfread
et qu'il y a une colonne sans nom, elle aura unV1
nom (etread.csv
donneraX
). Il est donc possible que votre table ait déjà un fichierV1
. Peut-être juste obtenir le nom parnames(DT)[length(names(DT))]
Pour plusieurs colonnes et une fonction appliquée sur les valeurs de colonne.
Lors de la mise à jour des valeurs d'une fonction, le RHS doit être un objet de liste, donc utiliser une boucle sur
.SD
aveclapply
fera l'affaire.L'exemple ci-dessous convertit les colonnes entières en colonnes numériques
a1 <- data.table(a=1:5, b=6:10, c1=letters[1:5]) sapply(a1, class) # show classes of columns # a b c1 # "integer" "integer" "character" # column name character vector nm <- c("a", "b") # Convert columns a and b to numeric type a1[, j = (nm) := lapply(.SD, as.numeric ), .SDcols = nm ] sapply(a1, class) # a b c1 # "numeric" "numeric" "character"
la source
Récupérez plusieurs colonnes de data.table via une variable ou une fonction:
library(data.table) x <- data.table(this=1:2,that=1:2,whatever=1:2) # === explicit call x[, .(that, whatever)] x[, c('that', 'whatever')] # === indirect via variable # ... direct assignment mycols <- c('that','whatever') # ... same as result of a function call mycols <- grep('a', colnames(x), value=TRUE) x[, ..mycols] x[, .SD, .SDcols=mycols] # === direct 1-liner usage x[, .SD, .SDcols=c('that','whatever')] x[, .SD, .SDcols=grep('a', colnames(x), value=TRUE)]
qui tous rapportent
that whatever 1: 1 1 2: 2 2
Je trouve la
.SDcols
voie la plus élégante.la source
Tu pourrais essayer ça
colname <- as.name ("COL_NAME")
DT2 <- DT [, list (COL_SUM = sum (eval (colname, .SD))), by = c (group)]
la source