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

如何用for循环在data.table中仅计算选定变量的相关性

解决data.table中按组计算指定变量相关性的报错问题

你遇到的'y' must be numeric错误,本质是调用cor(.SD, xcor)时,xcor是字符向量(列名),但cor函数的第二个参数需要接收数值向量,而不是列名。.SD是一个data.table对象,直接把列名传给cor,它无法自动识别为对应的数值列,所以触发了报错。

下面给你两种靠谱的解决方案,一种是更简洁的向量化写法(不用循环),另一种是修正后的for循环实现:

方案一:用lapply实现向量化计算(推荐)

这种写法更符合data.table的风格,代码简洁效率也高:

set.seed(1)
TDT <- data.table(Group = c(rep("A",40),rep("B",60)), Id = c(rep(1,20),rep(2,20),rep(3,20),rep(4,20),rep(5,20)), Time = rep(seq(as.Date("2010-01-03"), length=20, by="1 month") - 1,5), norm = round(runif(100)/10,2), y = sample(100,100), x2 = round(rnorm(100,0.75,0.3),2), x3 = round(rnorm(100,0.75,0.3),2), x4 = round(rnorm(100,0.75,0.3),2), x5 = round(rnorm(100,0.75,0.3),2))

# 获取数值型变量
numcols <- names(Filter(is.numeric, TDT))
# 定义需要计算相关性的目标自变量
xcor <- c("x2","x3")

# 按Time分组,计算每个xcor变量与所有数值变量的相关性
TDT.x.cor <- TDT[, 
                 lapply(xcor, function(var) cor(.SD, .SD[[var]])), 
                 .SDcols = numcols, 
                 by = Time]

# 重命名列,让结果更直观
setnames(TDT.x.cor, paste0("V", seq_along(xcor)), paste0("cor_with_", xcor))

这里用lapply遍历xcor中的每个变量名,通过.SD[[var]]提取对应的数值向量,再和.SD(所有数值列)计算相关性。最后用setnames给结果列重命名,方便后续查看。

方案二:修正后的for循环写法

如果你更习惯用循环,只需修正原代码的语法问题即可:

set.seed(1)
TDT <- data.table(Group = c(rep("A",40),rep("B",60)), Id = c(rep(1,20),rep(2,20),rep(3,20),rep(4,20),rep(5,20)), Time = rep(seq(as.Date("2010-01-03"), length=20, by="1 month") - 1,5), norm = round(runif(100)/10,2), y = sample(100,100), x2 = round(rnorm(100,0.75,0.3),2), x3 = round(rnorm(100,0.75,0.3),2), x4 = round(rnorm(100,0.75,0.3),2), x5 = round(rnorm(100,0.75,0.3),2))

numcols <- names(Filter(is.numeric, TDT))
xcor <- c("x2","x3")

# 初始化空list存储每个变量的相关性结果
cor_results <- list()

for (var in xcor) {
  # 计算当前变量与所有数值变量的相关性,并给结果列命名
  cor_results[[var]] <- TDT[, 
                            setNames(cor(.SD, .SD[[var]]), paste0("cor_with_", var)), 
                            .SDcols = numcols, 
                            by = Time]
}

# 按Time列合并所有结果
TDT.x.cor <- Reduce(function(a,b) merge(a,b, by = "Time"), cor_results)

原循环的问题在于:

  • 不需要把xcor定义为list,用普通字符向量即可
  • 不能用TDT.xcor[[i]].cor这种错误的赋值语法,先初始化list存储每个变量的结果,最后再合并成一个data.table

两种方案最终都会得到按Time分组的相关性结果,包含所有数值变量与x2、x3的相关性,也会自动包含y与这两个变量的相关性,和你之前计算的TDT.y.cor可以对应上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:21:52