You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R中使用data.table与.SD循环修改单行的技术问询

用data.table的.SD实现单行条件下的列均值计算

先明确示例场景的基础数据:

library(data.table)
# 构建示例数据表
temp <- data.table(
  a = c(10, 0),
  b = c(30, 10),
  worksA = NA_real_,
  worksB = NA_real_
)
# 初始化第一行的worksA、worksB
temp[1, `:=`(worksA = a, worksB = b)]

我们的目标是给第2行的worksA、worksB分别赋值为a、b列前两行的均值(即5和20)。

你尝试的代码出错原因分析

  1. temp[2, :=(tryA=mean(a[1:2]),tryB=mean(b[1:2]))] 生成NA
    当你用temp[2, ...]筛选行后,括号内的表达式是在第2行的局部环境中执行的。此时a[1:2]等效于temp[2, a][1:2]——也就是只取第2行的a值(0),再取前两个元素,第二个元素自然是NA,mean()计算包含NA的向量就会返回NA。

  2. temp[2, c("tryA", "tryB"):=lapply(.SD[1:2], mean), .SDcols=c("a", "b")] 生成NA
    和上面的问题本质一样:.SD在这里是筛选后的子集(仅第2行的a、b列),.SD[1:2]试图取这个子集的前两行,但子集只有1行,所以第二行是NA,均值计算结果还是NA。

  3. 添加na.rm=TRUE后仅计算当前行均值
    此时.SD[1:2]里只有当前行的有效值和一个NA,na.rm=TRUE会忽略NA,最终计算的就是当前行的数值,而非前两行的均值。

  4. 不指定行选择时所有行都被设为前两行均值
    没有行筛选条件时,.SD是整个数据表的a、b列,.SD[1:2]就是这两列的前两行数据,lapply计算出的均值会被赋值给所有行,所以所有行的tryA、tryB都会变成前两行的均值。

用.SD结合自定义函数实现单行修改的正确方式

要在单行修改时引用整个表的前两行数据,必须明确从完整数据表中取数,而非筛选后的子集。以下是几种可行方案:

方案1:通过.SDcols传递列名,自定义函数调用完整数据表

# 定义计算指定列目标行均值的函数
calc_row_mean <- function(col_name, dt, target_rows) {
  mean(dt[[col_name]][target_rows])
}

# 给第2行赋值
temp[2, c("worksA", "worksB") := lapply(.SDcols, calc_row_mean, dt=temp, target_rows=1:2), .SDcols=c("a", "b")]

方案2:直接在赋值表达式中引用完整数据表的.SD

temp[2, c("worksA", "worksB") := lapply(temp[, .SD, .SDcols=c("a", "b")][1:2], mean)]

验证结果

执行后查看数据表:

print(temp)
#    a  b worksA worksB
# 1:10 30     10     30
# 2: 0 10      5     20

完全符合预期。

内容的提问来源于stack exchange,提问作者Yohan Jaget

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 19:15:49