R data.table: How do you create a new column with a name from a string?

I have a vector of strings, and I need to create one new column in my data.table for each of them. Like so:

dt <- data.table(a = c(1,2,3), b = c(4,5,6))
column_names <- c("x", "y", "z")

I want to do something like this:

for (column_name in column_names) {
    dt[, column_name := paste0(column_name, a, b)]
}

This should result in something like this:

a | b |   x |   y |   z
-----------------------
1 | 4 | x14 | y14 | z14
2 | 5 | x25 | y25 | z25
3 | 6 | x36 | y36 | z36

But instead, it tries to create a column with the name "column_name" 3 times. How do I get around this?

3 answers

  • answered 2018-01-12 22:16 detroyejr

    Try wrapping column_name in parenthesis. For example:

    mtcars <- as.data.table(mtcars)
    
    for (col in names(mtcars)) {
    mtcars[, (col) := 1]
    }
    

    So as long as you can retrieve the assigned value in the for-loop, that should get you what you want.

  • answered 2018-01-12 22:16 Gautam

    Here's a quick and dirty way of doing this:

    CODE

    library(data.table)
    dt <- as.data.table(mtcars)
    col_names <- c("col1", "col2", "col3")
    for(i in 1:length(col_names)){
      dt[, paste(col_names[i]) := i]
    }
    

    OUTPUT

    > head(dt)
        mpg cyl disp  hp drat    wt  qsec vs am gear carb col1 col2 col3
    1: 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4    1    2    3
    2: 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4    1    2    3
    3: 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1    1    2    3
    4: 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1    1    2    3
    5: 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2    1    2    3
    6: 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1    1    2    3
    

    I'm sure there're more elegant ways of doing this.

  • answered 2018-01-12 22:16 Rob Jensen

    You may want to use .SD instead of a loop. Replace log with whatever function you want to apply to the columns.

    mtcars <- as.data.table(mtcars)
    columnstolog <- c('mpg', 'cyl', 'disp', 'hp')
    
    mtcars[, (columnstolog) := lapply(.SD, log), .SDcols = columnstolog]