如何将公式转换为变量以与 R 中的 fastLm 函数一起使用
How to turn formula to variables for use with fastLm function in R
出于性能原因,我正在尝试使用函数 RcppArmadillo::fastLM
而不是 lm
。
这是我对 lm
的函数调用
test_dt = structure(list(A= c(168.08, 166.65, 167.52, 167.16, 165.77,
167.65, 169.84, 170.45, 171.29, 173.15, 174.12, 174.45, 174.18,
172.92, 174.5, 173.94, 172.61, 168.74, 167.28, 167.12), `B` = c(1801.599976,
1783, 1795.099976, 1788.699951, 1763.599976, 1793, 1816.400024,
1827.400024, 1830.199951, 1847.599976, 1863.199951, 1867.900024,
1866.099976, 1853.599976, 1869.699951, 1861, 1851.199951, 1806,
1783.5, 1784.099976)), row.names = c(NA, -20L), class = c("data.table",
"data.frame"))
coef(lm(A ~ B + 0,data = test_dt))[1]
> 0.0934728
由于大部分时间都是lm在解释公式时使用的,所以我不想使用公式。相反,我想把它变成一些东西 -
RcppArmadillo::fastLM(X = test_dt$B + 0, y = test_dt$A)
但我不确定如何添加 + 0
,如公式所示。
我尝试了以下方法
library(data.table)
dt = copy(test_dt)
dt[, C := 0]
coef(RcppArmadillo::fastLm(X = dt[,2:3], y = dt[,1]))[[1]]
但是这是错误的。
Error in fastLm.default(X = dt[, 2:3], y = dt[, 1]) :
(list) object cannot be coerced to type 'double'
谁能告诉我将公式 A ~ B + 0
转换为变量 X
和 y
以便在 fastLm 函数中使用的正确方法?
这是性能结果。
microbenchmark::microbenchmark(
formula = coef(lm(A ~ B + 0, dt))[1],
fastLm = with(dt, coef(RcppArmadillo::fastLm(B, A)))[1],
flm = with(dt, collapse::flm(A, cbind(B)))[1],
times = 100)
Unit: microseconds
expr min lq mean median uq max neval cld
formula 1157.822 1173.249 1191.57071 1183.0080 1197.5560 1714.430 100 c
fastLm 219.785 228.086 240.30415 235.2545 244.7465 405.353 100 b
flm 67.595 71.902 76.91765 74.7790 77.2050 228.320 100 a
y
应该是一个向量。根据?fastLm
y - a vector containing the explained variable.
通过使用 dt[,1]
,drop = FALSE
in data.table
which returns a data.table with single column。相反,如果我们想要一个向量,请使用 [[
来提取列
fastLm(X = dt[, 2:3], y = dt[[1]])
fastLm 默认方法的第一个参数是模型矩阵。它应该有一列 1 来表示截距,如果没有,则没有截距。
这些不使用截距给出相同的答案:
coef(lm(A ~ B + 0, test_dt))[1]
with(test_dt, coef(fastLm(B, A)))
这些使用截距给出了相同的答案:
coef(lm(A ~ B, test_dt))
with(test_dt, coef(fastLm(cbind(1, B), A)))
出于性能原因,我正在尝试使用函数 RcppArmadillo::fastLM
而不是 lm
。
这是我对 lm
test_dt = structure(list(A= c(168.08, 166.65, 167.52, 167.16, 165.77,
167.65, 169.84, 170.45, 171.29, 173.15, 174.12, 174.45, 174.18,
172.92, 174.5, 173.94, 172.61, 168.74, 167.28, 167.12), `B` = c(1801.599976,
1783, 1795.099976, 1788.699951, 1763.599976, 1793, 1816.400024,
1827.400024, 1830.199951, 1847.599976, 1863.199951, 1867.900024,
1866.099976, 1853.599976, 1869.699951, 1861, 1851.199951, 1806,
1783.5, 1784.099976)), row.names = c(NA, -20L), class = c("data.table",
"data.frame"))
coef(lm(A ~ B + 0,data = test_dt))[1]
> 0.0934728
由于大部分时间都是lm在解释公式时使用的,所以我不想使用公式。相反,我想把它变成一些东西 -
RcppArmadillo::fastLM(X = test_dt$B + 0, y = test_dt$A)
但我不确定如何添加 + 0
,如公式所示。
我尝试了以下方法
library(data.table)
dt = copy(test_dt)
dt[, C := 0]
coef(RcppArmadillo::fastLm(X = dt[,2:3], y = dt[,1]))[[1]]
但是这是错误的。
Error in fastLm.default(X = dt[, 2:3], y = dt[, 1]) :
(list) object cannot be coerced to type 'double'
谁能告诉我将公式 A ~ B + 0
转换为变量 X
和 y
以便在 fastLm 函数中使用的正确方法?
这是性能结果。
microbenchmark::microbenchmark(
formula = coef(lm(A ~ B + 0, dt))[1],
fastLm = with(dt, coef(RcppArmadillo::fastLm(B, A)))[1],
flm = with(dt, collapse::flm(A, cbind(B)))[1],
times = 100)
Unit: microseconds
expr min lq mean median uq max neval cld
formula 1157.822 1173.249 1191.57071 1183.0080 1197.5560 1714.430 100 c
fastLm 219.785 228.086 240.30415 235.2545 244.7465 405.353 100 b
flm 67.595 71.902 76.91765 74.7790 77.2050 228.320 100 a
y
应该是一个向量。根据?fastLm
y - a vector containing the explained variable.
通过使用 dt[,1]
,drop = FALSE
in data.table
which returns a data.table with single column。相反,如果我们想要一个向量,请使用 [[
来提取列
fastLm(X = dt[, 2:3], y = dt[[1]])
fastLm 默认方法的第一个参数是模型矩阵。它应该有一列 1 来表示截距,如果没有,则没有截距。
这些不使用截距给出相同的答案:
coef(lm(A ~ B + 0, test_dt))[1]
with(test_dt, coef(fastLm(B, A)))
这些使用截距给出了相同的答案:
coef(lm(A ~ B, test_dt))
with(test_dt, coef(fastLm(cbind(1, B), A)))