Для петлевых альтернатив для прогрессивных операций - PullRequest
2 голосов
/ 24 февраля 2011

Мне нужно постепенно применять функцию регрессии к данным временного ряда (вектор "время" и "тм", и я использую цикл 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]
}

Но для векторов длиной около 10К это становится очень медленным. Есть ли более быстрая альтернатива (возможно, с помощью функции apply)?

В более простой задаче: если у меня есть вектор типа x <-c (1:10), как я могу построить вектор y, содержащий (например) прогрессивную сумму значений x? Как: </p>

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

Ответы [ 2 ]

3 голосов
/ 24 февраля 2011

Ну, нет быстрой альтернативы цикла, если вы не можете векторизовать. В некоторых случаях такие функции, как ave, aggregate, ddply, tapply, ..., могут дать вам существенный выигрыш, но часто хитрость заключается в использовании более быстрых функций, таких как cumsum (см. Ответ пользователя 615147)

Для иллюстрации:

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(). Не заблуждайтесь, временные интервалы немного различаются при каждом запуске анализа, поэтому разница в 0,02 незначительна в R. sapply, for и lapply здесь все так же быстро. Хитрость заключается в том, чтобы использовать 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]
)

как более общее решение.

0 голосов
/ 24 февраля 2011
results <- sapply(2:top,function (k) coef(lm(tm[1:k] ~ log(time[1:k])))[2])

~ применить семейство функций - самый быстрый способ итерации в R.

также можете посмотреть, как использовать lm.fit (), чтобы немного ускорить вашу регистрацию.

cumsum(1:10)

это как сделать второй вопрос

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...