Home > Blockchain >  How to turn formula to variables for use with fastLm function in R
How to turn formula to variables for use with fastLm function in R

Time:12-09

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]])
  • Related