r - 循环遍历 data.table 中的列并转换这些列

标签 r data.table

我有一个 data.table DT,其中有一个名为 RF 的列,以及许多带有下划线 _ 的列。我想用一个循环遍历所有这些列 下划线并从中减去 RF 列。但是,我被困住了。似乎 RHS 上的所有内容 data.table 中的 := 运算符不适用于动态变量。

这是我的DT和所需的输出(硬编码):

library(data.table)
DT <- data.table(RF  = 1:10,
                 S_1 = 11:20,
                 S_2 = 21:30)
#Desired output
DT[ , S_1 := S_1 - RF]
DT[ , S_2 := S_2 - RF]
DT
      RF S_1 S_2
 [1,]  1  10  20
 [2,]  2  10  20
 [3,]  3  10  20
...

但是,我希望它更加灵活,即循环遍历名称中带有“_”的每一列并减去RF:

#1. try: Does not work; Interestingly, the i on the LHS of := is interpreted as the column i, but on the RHS of
#:= it is interpreted as 2 and 3, respectively
for (i in grep("_", names(DT))){
  DT[ , i:= i - 1, with=FALSE]
}
DT
          RF  S_1 S_2
 [1,]  1   1   2
 [2,]  2   1   2
 [3,]  3   1   2
...

#2. try: Work with parse and eval
for (i in grep("_", names(DT), value=TRUE)){
  DT[ , eval(parse(text=i)):= eval(parse(text=i)) - RF]
}
#Error in eval(expr, envir, enclos) : object 'S_1' not found

任何关于如何做到这一点的提示都会很棒。

编辑:我一发布问题,我就想:你为什么要使用 := 运算符,果然,我刚刚意识到我不这样做必须。这确实有效并且不需要循环:

DT[, grep("_", names(DT)), with=FALSE] - DT[, RF]

抱歉。不过,我没有回答这个问题,因为我仍然对为什么我使用 := 运算符的方法不起作用感兴趣。所以也许有人可以帮助我。

最佳答案

您的第二次尝试走上了正确的道路。下面是一种使用 substitute 构建表达式的方法,该表达式作为 DT[ , j ] 中的 'j' 参数传入。

for (i in grep("_", names(DT), value=TRUE)){
    e <- substitute(X := X - RF, list(X = as.symbol(i)))
    DT[ , eval(e)]
}
DT
#     RF S_1 S_2
# [1,]  1  10  20
# [2,]  2  10  20
# [3,]  3  10  20
# [4,]  4  10  20
# [5,]  5  10  20
<小时/>

您还可以使用 LHS 表达式而不是符号:

for (i in grep("_", names(DT), value=TRUE))
    DT[, (i) := get(i)-RF]

关于r - 循环遍历 data.table 中的列并转换这些列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8374816/

相关文章:

r - R中的参数传递机制

r - 从最佳 R Caret 模型中提取获胜的 RMSE

R:在 ifelse 函数中使用 "()"内的逻辑语句在 data.table 中分配变量

r - 使用 data.table 将 lm 函数应用于不同范围的数据和单独的组

r - 根据一组最大值降序排列,然后删除 dplyr 中的最大值列

r - 根据分组变量计算百分比

r - CSV文件到R中的直方图

r - data.table:在使用关键变量的单调变换时绕过 setkey

r - 合并 data.table 时出错 - 编码警告消息

从 R 中的 data.table 有条件地删除行