考虑以下演示数据:
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()和相关函数来说是必要的呢?
发布于 2014-02-12 00:19:00
使用debugonce(model.matrix.default),并在其中使用tracemem(data)
model.matrix.default调用model.frame,它返回一个data.frame。在model.matrix.default中,此data.frame至少复制3次。
为什么lm使用model.matrix -> lm通常以data.frame、list或environment作为data参数调用。model.frame和返回一个data.frame可以确保公式中的术语可以通过随后对lm的调用找到,并将引用相同的值。
发布于 2014-02-12 03:40:59
通常,对Rprof的调用(在默认情况下应该位于search()路径上的library(utils)中)将说明在函数调用中时间开销来自何处:
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.omit.data.frame检查na.omit.data.frame的data.frame,并在model.frame.default中用[.data.frame替换data.frame。时间的比例将根据样本大小n而变化,但对于大样本大小则趋向于一个限制。
https://stackoverflow.com/questions/21715549
复制相似问题