【问题标题】:Computing squared residual in regression row-wise in a data.table在 data.table 中逐行计算回归残差的平方
【发布时间】:2016-11-23 18:03:18
【问题描述】:

假设我有一个 data.tableX1,X2,X3,Y。对于每一行,我想将X1,X2,X3 中的条目视为长度为 3 的向量,取固定向量的内积,例如长度为 4 的 beta,从输入Y,对结果求平方,然后输出每一行的最终结果(或将其另存为另一列)。

经过大量研究,我想出了这个

dat[, (Y-sum(.SD*beta))^2, .SDcols=c(1:3)]

没有按预期工作。

奖励点 #1:将 3 替换为一般的 n

奖励点 #2:假设我有一个包含组索引的 grp 列,我想按组对这些残差平方进行平均。

【问题讨论】:

  • 下一次,考虑像 Gregor 所做的那样包含一个完整的可重现示例。
  • @Frank,会试试的。

标签: r data.table


【解决方案1】:

假设y 是数据表dat 的第一列,其余列是预测变量。这适用于奖金 1。

mat = as.matrix(dat[, x1:x3, with = F])
pred = cbind(1, mat) %*% beta
dat[, rss := (pred - y)^2]

对于奖金 2:

dat[, mean_by_grp := mean(rss), by = grp]

为避免矩阵转换,您可以这样做:

dat[, pred := beta[1] + beta[2] * x1 + beta[3] * x2 + beta[4] * x3]

写出内积。


完整的可重现示例

set.seed(47)
dat = data.table(replicate(4, rnorm(5)))
setnames(dat, c("y", paste0("x", 1:3)))
dat[, grp := c("A", "A", "B", "B", "B")]
beta = 1:4

mat = as.matrix(dat[, x1:x3, with = F])
pred = cbind(1, mat) %*% beta
dat[, rss := (pred - y) ^ 2]

dat[, mean_by_grp := mean(rss), by = grp]
dat
#             y          x1          x2          x3 grp       rss mean_by_grp
# 1:  1.9946963 -1.08573747 -0.92245624  0.67077922   A 10.565250    7.064164
# 2:  0.7111425 -0.98548216  0.03960243 -0.08107805   A  3.563078    7.064164
# 3:  0.1854053  0.01513086  0.49382018  1.26424109   B 54.512843   38.263204
# 4: -0.2817650 -0.25204590 -1.82822917 -0.70338819   B 56.558929   38.263204
# 5:  0.1087755 -1.46575030  0.09147291 -0.04057817   B  3.717840   38.263204

【讨论】:

  • 好的,谢谢。有没有更好的办法? pred 是在 data.table 之外计算的。将每一行的“x”和“y”传递给逐行操作的函数应该是一种自然的方式。我不想将 data.table 转换为矩阵。
  • 这是更好的方法。矩阵乘法是高度优化的。逐行操作是执行此操作的缓慢方法。
  • 一般来说,矩阵乘法是线性代数包的优化对象。您将无法对此进行改进。尽管您可以切换编译 R 的库。参见,例如,Faster R through better BLAS
  • 逐行是完全错误的方式。您听说过 R 在矢量化方面的优势,对吧?逐行执行会禁用矢量化。
  • 好吧,也许您应该创建一个可重现的示例。我做的那个对我来说很好。我会添加它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-30
  • 2020-02-07
  • 1970-01-01
  • 1970-01-01
  • 2017-01-14
  • 2017-10-03
  • 2017-05-27
相关资源
最近更新 更多