4

I want to add a column to a data.table. But the name of this new column have to be extract from a character vector. I write this :

add_var=function(index){
  label=c("products","price")
  var_name=label[index]
  df=data.frame(x=c(1,2,5,9),y=c(5,2,6,7))
  dt=as.data.table(df)
  dt[,(as.name(var_name)):=5]
  return(dt)
}
new_ds=add_var(1)

And I expected something like

x y products
1 5        5
2 2        5
5 6        5
9 7        5

But, instead, I got this error message :

 Error in `[.data.table`(dt, , `:=`((as.name(var_name)), 5)) : 
  LHS of := must be a symbol, or an atomic vector (column names or positions). 

Anyone know how to fix my function to make it work?

hans glick
  • 2,431
  • 4
  • 25
  • 40
  • 2
    Don't use `as.name` there. `:=` expects a character vector on the LHS. Also, you can construct a data.table directly using `data.table`. Finally, use `return(dt[])` to [ensure the data.table is printed](http://stackoverflow.com/q/32988099/1412059) the first time after calling the function. – Roland Jun 03 '16 at 10:50
  • Also, `setDT(df)` is more memory-efficient and much faster than `dt=as.data.table(df)` – rafa.pereira Jun 03 '16 at 10:56

1 Answers1

5

You just need this:

label <- c("products","price")
df <- data.frame(x=c(1,2,5,9),y=c(5,2,6,7))


setDT(df)[ , (label) := 5]


#>    x y label products price
#> 1: 1 5     5        5     5
#> 2: 2 2     5        5     5
#> 3: 5 6     5        5     5
#> 4: 9 7     5        5     5
rafa.pereira
  • 13,251
  • 6
  • 71
  • 109
  • 1
    Great! Can you tell me more about setDT? Actually it works with this command setDT(dt)[ , (var_name) := 5] – hans glick Jun 03 '16 at 10:55
  • 3
    `setDT(df)` converts a `data.frame` into a `data.table` without copying it into memory. You could also do it in two separate steps, first `setDT(df)` and then `df[ , (label) := 5]`. If you want to convert it back into a `data.framte`, it's simple as `setDF(df)` – rafa.pereira Jun 03 '16 at 11:01
  • waouw! great! thks! – hans glick Jun 03 '16 at 11:13