对具有可变列名称的数据 table 的操作
Operations on data table with variable column name
我正在尝试对作为变量传递的 data.table
的列执行操作。
这是一个玩具示例:
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
假设感兴趣的列作为变量值传递:
> print(target.column <- sample(colnames(DT), 1))
[1] "V3"
所以我想对列 V3
执行一些操作,例如,为简单起见,将值下限为 0.5。我已经通过使用可怕的 paste
、parse
和 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
但我的其他尝试均未成功:
> 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
我已经在 SO 上寻找解决方案,但 ol' interweb 找不到任何有用的东西...有 "data.table" 方法可以做到这一点吗?
您可以使用
DT[ get(target.column) < .5, (target.column) := .5]
给出了想要的结果。
您的代码的修改将使用 eval(as.symbol(
或 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
我正在尝试对作为变量传递的 data.table
的列执行操作。
这是一个玩具示例:
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
假设感兴趣的列作为变量值传递:
> print(target.column <- sample(colnames(DT), 1))
[1] "V3"
所以我想对列 V3
执行一些操作,例如,为简单起见,将值下限为 0.5。我已经通过使用可怕的 paste
、parse
和 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
但我的其他尝试均未成功:
> 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
我已经在 SO 上寻找解决方案,但 ol' interweb 找不到任何有用的东西...有 "data.table" 方法可以做到这一点吗?
您可以使用
DT[ get(target.column) < .5, (target.column) := .5]
给出了想要的结果。
您的代码的修改将使用 eval(as.symbol(
或 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