我在 R 中有一个非常大的表,其中的数字列给出了几年的值。它看起来像这样,但有更多的列和数百万行。
id year1 year2 year3 year4
ac 44 34 23 34
as 12 15 25 45
df 99 88 107 114
我想计算一个新列,给出数字列随时间变化的趋势。我猜这可能是数字列回归的斜率。我怎样才能有效地计算每一行的值?使用
data.table
的建议将是理想的选择。
到目前为止,我已经能够通过将数据重新整形为长数据并通过
id
执行回归来做到这一点。我想知道是否有更有效的方法来做到这一点而不需要重新塑造。
手动进行线性回归可以在几秒钟内处理 1e7 行和 50 列:
library(Rfast)
library(collapse)
library(data.table)
set.seed(509437570)
nr <- 1e7 # number of rows
nc <- 50 # number of columns
dt <- data.table(id = 1:nr)[
,paste0("year", 1:nc) :=
as.data.frame(matrix(rnorm(nr*nc, 0, 5) + outer(runif(nr), 1:nc), nr, nc))
]
system.time(
dt[
,c("slope", "intercept") := .(
slope <- (setop(m <- as.matrix(.SD), "-", ybar <- rowmeans(m)) %*%
(dx <- seq(-(nc - 1)/2, (nc - 1)/2)))/sum(dx^2),
ybar - slope*(nc + 1)/2
), .SDcols = paste0("year", 1:nc)
]
)
#> user system elapsed
#> 5.25 0.53 3.72
dt[1:5, c("id", "slope", "intercept")]
#> id slope intercept
#> 1: 1 0.1821816 2.6856957
#> 2: 2 0.3254113 0.1084359
#> 3: 3 0.4975937 0.4861745
#> 4: 4 0.3796465 1.0722193
#> 5: 5 0.6800638 -0.3818551
绘制适合的第一行:
plot(1:nc, unlist(dt[1, 2:(nc + 1)]))
abline(dt$intercept[1], dt$slope[1])