Reputation: 6913
I am trying to perform operations on a data.table
's column that is passed as a variable.
Here is a toy example:
library(data.table)
set.seed(2)
DT <- data.table(replicate(3, runif(4)))
> DT
V1 V2 V3
1: 0.1848823 0.9438393 0.4680185
2: 0.7023740 0.9434750 0.5499837
3: 0.5733263 0.1291590 0.5526741
4: 0.1680519 0.8334488 0.2388948
Say the column of interest is passed as the value of a variable:
> print(target.column <- sample(colnames(DT), 1))
[1] "V3"
So I would like to perform some operation on column V3
, say, flooring the value at 0.5 for simplicity. I have successfully made this work by using the dreaded paste
, parse
and eval
:
> eval(parse(text = paste0("DT[", target.column, " < 0.5, ", target.column, " := 0.5, ]")))
V1 V2 V3
1: 0.1848823 0.9438393 0.5000000
2: 0.7023740 0.9434750 0.5499837
3: 0.5733263 0.1291590 0.5526741
4: 0.1680519 0.8334488 0.5000000
But have been unsuccessful in my other attempts:
> DT[eval(target.column) < 0.5, eval(target.column) := 0.5, ]
V1 V2 V3
1: 0.1848823 0.9438393 0.4680185
2: 0.7023740 0.9434750 0.5499837
3: 0.5733263 0.1291590 0.5526741
4: 0.1680519 0.8334488 0.2388948
> DT[as.name(target.column) < 0.5, as.name(target.column) := 0.5, ]
V1 V2 V3
1: 0.1848823 0.9438393 0.4680185
2: 0.7023740 0.9434750 0.5499837
3: 0.5733263 0.1291590 0.5526741
4: 0.1680519 0.8334488 0.2388948
> DT[deparse(substitute(target.column)) < 0.5, deparse(substitute(target.column)) := 0.5, ]
V1 V2 V3
1: 0.1848823 0.9438393 0.4680185
2: 0.7023740 0.9434750 0.5499837
3: 0.5733263 0.1291590 0.5526741
4: 0.1680519 0.8334488 0.2388948
I have looked for solutions on SO and the ol' interweb have not been able to find anything useful... is there a "data.table" way to do this?
Upvotes: 0
Views: 245
Reputation: 886938
A modification of your code will be to use eval(as.symbol(
or eval(as.name(
DT[ eval(as.symbol(target.column)) < .5, (target.column):= .5][]
# V1 V2 V3
#1: 0.1848823 0.9438393 0.5000000
#2: 0.7023740 0.9434750 0.5499837
#3: 0.5733263 0.1291590 0.5526741
#4: 0.1680519 0.8334488 0.5000000
Upvotes: 1
Reputation: 66819
You can use
DT[ get(target.column) < .5, (target.column) := .5]
which gives the desired result.
Upvotes: 4