【问题标题】:For Loop alternatives for progressive operations渐进式操作的 For Loop 替代方案
【发布时间】:2011-02-24 15:58:32
【问题描述】:

我必须逐步将回归函数应用于时间序列数据(向量“时间”和“tm”,我正在使用如下的 For 循环:

top<-length(time)
for(k in 2:top){
    lin.regr<-lm(tm[1:k] ~ log(time[1:k]))
    slope[k]<-coef(lin.regr)[2]
}

但是对于大约 10k 的向量长度,它变得非常慢。 有没有更快的替代方案(也许使用 apply 函数)?

在一个更简单的问题中:如果我有一个像 x

x
1 2 3 4 5 6 7 8 9 10
y
1  3  6 10 15 21 28 36 45 55

【问题讨论】:

标签: r time-series apply progressive


【解决方案1】:

嗯,没有快速循环替代方案,除非你可以矢量化。在某些情况下,像 ave, aggregate, ddply, tapply, ... 这样的函数可以给你带来巨大的胜利,但诀窍通常在于使用更快的函数,比如 cumsum(参见 user615147 的答案)

为了说明:

top <- 1000
tm <- rnorm(top,10)   
time <- rnorm(top,10)

> system.time(
+ results <- sapply(2:top,function (k) coef(lm(tm[1:k] ~ log(time[1:k])))[2])
+ )
   user  system elapsed 
   4.26    0.00    4.27 

> system.time(
+ results <- lapply(2:top,function (k) coef(lm(tm[1:k] ~ log(time[1:k])))[2])
+ )
   user  system elapsed 
   4.25    0.00    4.25 

> system.time(
+ results <- for(k in 2:top) coef(lm(tm[1:k] ~ log(time[1:k])))[2]
+ )
   user  system elapsed 
   4.25    0.00    4.25 

> system.time(
+ results <- for(k in 2:top) lm.fit(matrix(log(time[1:k]),ncol=1),
+                                 tm[1:k])$coefficients[2]
+ )
   user  system elapsed 
   0.43    0.00    0.42 

唯一更快的解决方案是lm.fit()。不要误会,每次运行分析时时间都会有所不同,因此 R 中 0.02 的差异并不显着。sapply, forlapply 在这里都一样快。诀窍是使用lm.fit

如果你有一个名为 Data 的数据框,你可以使用类似的东西:

Data <- data.frame(Y=rnorm(top),X1=rnorm(top),X2=rnorm(top))

mf <- model.matrix(Y~X1+X2,data=Data)
results <- sapply(2:top, function(k)
  lm.fit(mf[1:k,],Data$Y[1:k])$coefficients[2]
)

作为更通用的解决方案。

【讨论】:

    【解决方案2】:
    results <- sapply(2:top,function (k) coef(lm(tm[1:k] ~ log(time[1:k])))[2])
    

    ~apply 系列函数是在 R 中迭代最快的方法。

    也可以考虑使用 lm.fit() 来加快你的回归速度

    cumsum(1:10)
    

    第二个问题是怎么做的

    【讨论】:

    猜你喜欢
    • 2011-12-04
    • 2018-10-05
    • 2020-11-10
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 2019-09-24
    • 2020-08-31
    • 2018-02-19
    相关资源
    最近更新 更多