I am trying to use function RcppArmadillo::fastLM
instead of lm
for performance reasons.
Here is my function call to 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
since most of the time is used by lm in interpreting formula, I do not want to use formula. Instead, I want to turn it into something -
RcppArmadillo::fastLM(X = test_dt$B 0, y = test_dt$A)
but I am not sure how to add 0
as shown in the formula.
I have tried the following
library(data.table)
dt = copy(test_dt)
dt[, C := 0]
coef(RcppArmadillo::fastLm(X = dt[,2:3], y = dt[,1]))[[1]]
But this is giving error.
Error in fastLm.default(X = dt[, 2:3], y = dt[, 1]) :
(list) object cannot be coerced to type 'double'
Can someone show me the right way to turn formula A ~ B 0
into variables X
and y
for use in fastLm function?
Here are the performance results.
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
CodePudding user response:
The first argument of the default method of fastLm is the model matrix. It should have a column of 1's to represent the intercept and if it does not then there is no intercept.
These give the same answer using no intercept:
coef(lm(A ~ B 0, test_dt))[1]
with(test_dt, coef(fastLm(B, A)))
and these give the same answer using an intercept:
coef(lm(A ~ B, test_dt))
with(test_dt, coef(fastLm(cbind(1, B), A)))
CodePudding user response:
The y
should be a vector. According to ?fastLm
y - a vector containing the explained variable.
By using dt[,1]
, the drop = FALSE
in data.table
which returns a data.table with single column. Instead, if we want a vector, use [[
to extract the column
fastLm(X = dt[, 2:3], y = dt[[1]])