考虑以下演示数据:
set.seed(1)
n <- 1000000
x1 <- rnorm(n)
x2 <- rnorm(n)
x3 <- rnorm(n)
如果我使用mt
构建矩阵model.matrix()
,则需要永远:
system.time(mt <- model.matrix(~x1+x2+x3))
usuário sistema decorrido
0.916 0.185 1.135
但如果我对矩阵做同样的事情,那就很快了:
system.time(mt2 <- matrix(c(rep(1, n), x1, x2, x3), byrow=FALSE, ncol=4))
usuário sistema decorrido
0.085 0.021 0.105
为何与众不同? model.matrix()
和相关函数真正需要lm()
慢的原因是什么?
答案 0 :(得分:3)
使用debugonce(model.matrix.default)
,并使用tracemem(data)
model.matrix.default
调用model.frame
,返回data.frame
。在model.matrix.default
内,此data.frame至少复制3次。
为什么lm
使用model.matrix
- &gt;通常使用lm
,data.frame
或list
作为environment
参数调用data
。 model.frame
并返回data.frame
可确保后续调用lm
可以找到公式中的字词,并且会引用相同的值。
答案 1 :(得分:1)
一般情况下,Rprof
(library(utils)
中默认情况下应位于search()
路径上)的调用将说明函数调用中时间开销的来源:
Rprof("Rprof.out")
m1 <- model.matrix( ~ x1 + x2 + x3)
Rprof(NULL)
summaryRprof("Rprof.out")
给
> summaryRprof("Rprof.out")
$by.self
self.time self.pct total.time total.pct
"model.matrix.default" 0.12 42.86 0.28 100.00
"na.omit.data.frame" 0.06 21.43 0.14 50.00
"[.data.frame" 0.04 14.29 0.08 28.57
"anyDuplicated.default" 0.04 14.29 0.04 14.29
"as.list.data.frame" 0.02 7.14 0.02 7.14
$by.total
total.time total.pct self.time self.pct
"model.matrix.default" 0.28 100.00 0.12 42.86
"model.matrix" 0.28 100.00 0.00 0.00
"na.omit.data.frame" 0.14 50.00 0.06 21.43
"model.frame" 0.14 50.00 0.00 0.00
"model.frame.default" 0.14 50.00 0.00 0.00
"na.omit" 0.14 50.00 0.00 0.00
"[.data.frame" 0.08 28.57 0.04 14.29
"[" 0.08 28.57 0.00 0.00
"anyDuplicated.default" 0.04 14.29 0.04 14.29
"anyDuplicated" 0.04 14.29 0.00 0.00
"as.list.data.frame" 0.02 7.14 0.02 7.14
"as.list" 0.02 7.14 0.00 0.00
"vapply" 0.02 7.14 0.00 0.00
$sample.interval
[1] 0.02
$sampling.time
[1] 0.28
因此,在NA
内检查na.omit.data.frame
并在data.frame
内将[.data.frame
与model.frame.default
进行分组,花费了大量时间。时间的比例将根据样本大小n
而有所不同,但是对于大样本大小会有限制。