Когда у вас столько факторов, построение model.matrix в lm()
займет большую часть времени, один из способов - использовать sparseMatrix, как в glmnet
, и есть два пакета: sparseM
, MatrixModels
который позволяет lm на sparseMatrix:
set.seed(111)
x <- data.frame(
a = sample( 1:1000, 1000000 , replace=T),
cityfips = sample( 1:250, 1000000 , replace=T),
d = sample( 1:4, 1000000 , replace=T)
)
library(SparseM)
library(MatrixModels)
library(Matrix)
system.time(f_lm <- lm( a~as.factor(cityfips) + d , x ) )
user system elapsed
75.720 2.494 79.365
system.time(f_sparseM <- slm(a~as.factor(cityfips) + d , x ))
user system elapsed
5.373 3.952 10.646
system.time(f_modelMatrix <- glm4(a~as.factor(cityfips) + d ,data=x,sparse=TRUE))
user system elapsed
1.878 0.335 2.219
Наиболее близким, который я могу найти, является glm4 в MatrixModels
, но вы можете увидеть, что ниже коэффициенты такие же, как и при использовании lm:
all.equal(as.numeric(f_sparseM$coefficients),as.numeric(f_lm$coefficients))
[1] TRUE
all.equal(as.numeric(f_lm$coefficients),as.numeric(coefficients(f_modelMatrix)))
[1] TRUE
Еще одна опция, кроме glm4
в MatrixModels
, заключается в использовании lm.fit (как указано @BenBolker:
lm.fit(x=Matrix::sparse.model.matrix(~as.factor(cityfips) + d,data=x),y=x$a)
. Это дает вам список, как обычно lm.fit()
, и вы не может применять такие функции, как summary()
et c.
Авторы обоих пакетов предупреждают о том, что он экспериментальный, поэтому могут существовать некоторые различия по сравнению с stats::lm
, позаботьтесь о проверке.