Search code examples
rdata.table

Dynamically operate on column (inside :=)


I have the below data table

library(data.table)

df <- data.table(col1 = 1:3
                 , col2 = 2:4
                 )

I would like to dynamically operate on a column, whose column name is stored in the below object:

metric <- 'col2'

but the below failed

df[, `:=` (col1 = col1 - 1
           , as.name(metric) = as.numeric(get(metric))
           )
   ]

error:

Error: unexpected '=' in:
"df[, `:=` (col1 = col1 - 1
           , as.name(metric) ="

I would like to operate on col1 and whatever column whose name is stored in metric in one call. Are there any methods other than the below (which works)

df[, c('col1', metric) := .(col1 - 1
                            , as.numeric(get(metric))
                            )
   ]

Solution

  • Using get() in data.table has been retired. I think the proper way to do this these days is using env.

    I'll add 2 to the assignment so we can see it is modifying something:

    df[, `:=`(
        col1 = col1 - 1,
        col = as.numeric(col) + 2
    ), env = list(col = metric)][]
    
    #     col1  col2
    #    <num> <num>
    # 1:     0     4
    # 2:     1     5
    # 3:     2     6
    

    Or using let(), which is an alias for `:=` as suggested by Roland in the comments:

    df[,
        let(
            col1 = col1 - 1,
            col = as.numeric(col) + 2
        ),
        env = list(col = metric)
    ] # same result