2
votes

Utiliser data.table dans une autre fonction de R

Lors de la création d'une nouvelle variable avec des colonnes, data.table n'autorise pas les noms de colonnes entre guillemets. Cela génère le problème suivant lors de l'utilisation d'une table data.table dans une fonction.

addColumns <- function(dt,v1,v2){

  v1<-as.character(substitute(v1))
  v2<-as.character(substitute(v2))

  dt[,eval(parse(text=v1)) + eval(parse(text=v2))]
}

addColumns(dt, var1, var2)
[1]  3  6  9 12 15 18 21 24 27 30
addColumns(dt, "var1", "var2")
[1]  3  6  9 12 15 18 21 24 27 30

La solution de contournement suivante gère ce problème.

library(data.table) 
dt <- data.table(var1 = c(1:10), var2 = seq(2,20,2), var3 = seq(40,4,-4))    

addColumnsError <- function(dt, v1, v2){
  dt[,v1 + v2]
}

addColumnsError(dt, var1, var2)
>  Error in eval(jsub, SDenv, parent.frame()) : object 'var1' not found 

addColumnsError(dt, "var1", "var2")
>   Error in v1 + v2 : non-numeric argument to binary operator

Existe-t-il une manière plus élégante de passer des noms de colonnes à un objet data.table dans une fonction?

(Remarque: je pourrais simplement appeler la fonction data.table mais j'ai l'intention de faire des calculs plus compliqués :)) p>


0 commentaires

3 Réponses :


1
votes

Je pense que vous recherchez get ()!

library(data.table) 
dt <- data.table(var1 = c(1:10), var2 = seq(2,20,2), var3 = seq(40,4,-4))    

addColumnsError <- function(dt, v1, v2){
  dt[,get(v1) + get(v2)]
}

addColumnsError(dt, "var1", "var2")

Meilleur !


0 commentaires

2
votes

Si vous souhaitez utiliser une évaluation non standard, vous avez besoin de quelque chose comme substitut . Cependant, il n'y a absolument aucune raison d'utiliser parse.

addColumnsError <- function(dt, v1, v2){
  eval(substitute(dt[, v1 + v2]))
}

addColumnsError(dt, var1, var2)
#[1]  3  6  9 12 15 18 21 24 27 30


0 commentaires

1
votes

En utilisant .SDcols (qui accepte les caractères), vous pouvez faire:

addColumns <- function(dt, v1, v2){
  dt[, .SD[[1]] + .SD[[2]], .SDcols = c(v1, v2)]
}

# or more elegantly:
addColumns <- function(dt, v1, v2){
  dt[, rowSums(.SD), .SDcols = c(v1, v2)]
}

addColumns(dt, "var1", "var2")
# [1]  3  6  9 12 15 18 21 24 27 30


0 commentaires