r - R data.table:通过分组有效地访问和更新 j 表达式中的变量列名
问题描述
我想对数据表中的列列表应用一个转换(其类型,松散地说,是“向量”->“向量”),这个转换将涉及分组操作。
这是设置和我想要实现的目标:
library(data.table)
set.seed(123)
n <- 1000
DT <- data.table(
date = seq.Date(as.Date('2000/1/1'), by='day', length.out = n),
A = runif(n),
B = rnorm(n),
C = rexp(n))
DT[, A.prime := (A - mean(A))/sd(A), by=year(date)]
DT[, B.prime := (B - mean(B))/sd(B), by=year(date)]
DT[, C.prime := (C - mean(C))/sd(C), by=year(date)]
目标是避免输入列名。在我的实际应用程序中,我有一个我想应用此转换的列列表。
library(data.table)
set.seed(123)
n <- 1000
DT <- data.table(
date = seq.Date(as.Date('2000/1/1'), by='day', length.out = n),
A = runif(n),
B = rnorm(n),
C = rexp(n))
columns <- c("A", "B", "C")
for (x in columns) {
# This doesn't work.
# target <- DT[, (x - mean(x, na.rm=TRUE))/sd(x, na.rm = TRUE), by=year(date)]
# This doesn't work.
#target <- DT[, (..x - mean(..x, na.rm=TRUE))/sd(..x, na.rm = TRUE), by=year(date)]
# THIS WORKS! But it is tedious writing "get(x)" every time.
target <- DT[, (get(x) - mean(get(x), na.rm=TRUE))/sd(get(x), na.rm = TRUE), by=year(date)][, V1]
set(DT, j = paste0(x, ".prime"), value = target)
}
问题:实现上述结果的惯用方法是什么?有两点可以改进:
- 如何避免
get(x)
每次使用x
访问列时都输入内容? - 访问
[, V1]
是最有效的方法吗?是否可以通过引用直接更新DT
,而不创建中间data.table?
解决方案
您可以使用.SDcols
指定要操作的列:
library(data.table)
columns <- c("A", "B", "C")
newcolumns <- paste0(columns, ".prime")
DT[, (newcolumns) := lapply(.SD, function(x) (x- mean(x))/sd(x)),
year(date), .SDcols = columns]
这避免了get(x)
每次使用和data.table
通过引用更新。
推荐阅读
- c# - 使用 Microsoft Web 管理 C# 在单个服务级别设置 Windows 身份验证
- excel - Excel - 基于包含范围字符串的单元格绘制图表(间接?)
- python-3.x - 使用 where 子句从数据库中获取特定数据,从用户提供值以使用 python 打印与他相关的数据
- entity-framework - 在 EF Code First 中生成外键的问题 - 无法确定关联的主体端
- trace32 - 过滤每个 CPU 的跟踪输出
- javascript - 如何在 D3 V4 中的 nest() 函数后访问处理后的数据集?
- aws-lambda - 为什么lambda在代码提交中显示错误
- javascript - 如何在某些符号后剪切单词?
- regex - 匹配不包含数字的完整字符串,- 和+
- python - 醉酒步行班