Замена циклов for на apply для улучшения производительности (weighted.mean) - PullRequest
3 голосов
/ 07 марта 2012

Я новичок в R, так что, надеюсь, это решаемая проблема для некоторых из вас.У меня есть датафрейм, содержащий более миллиона точек данных.Моя цель - вычислить взвешенное среднее с изменяющейся начальной точкой.

Для иллюстрации рассмотрим этот кадр (data.frame (matrix (c (1,2,3,2,2,1), 3,2))))

  X1 X2
1  1  2
2  2  2
3  3  1

, где X1 - данные, а X2 - вес выборки.

Я хочу вычислить средневзвешенное значение для X1 от начальной точки 1 до 3, от 2: 3и из 3: 3.

С помощью цикла я просто написал:

B <- rep(NA,3) #empty result vector
for(i in 1:3){
  B[i] <- weighted.mean(x=A$X1[i:3],w=A$X2[i:3]) #shifting the starting point of the data and weights further to the end
} 

С моими реальными данными это невозможно вычислить, потому что для каждой итерации data.frame изменяется и вычисляетсязанимает часы без результата.

Есть ли способ реализовать начальную точку переменной с помощью команды apply, чтобы увеличить производительность?

С уважением, Рубен

Ответы [ 2 ]

3 голосов
/ 08 марта 2012

Опираясь на ответ @ joran для получения правильного результата:

with(A, rev(cumsum(rev(X1*X2)) / cumsum(rev(X2))))
# [1] 1.800000 2.333333 3.000000

Также обратите внимание, что это намного быстрее, чем подход sapply / lapply.

1 голос
/ 08 марта 2012

Вы можете использовать lapply для создания своих подмножеств и sapply для их зацикливания, но я бы поспорил, что будет более быстрый путь.

sapply(lapply(1:3,":",3),function(x) with(dat[x,],weighted.mean(X1,X2)))
[1] 1.800000 2.333333 3.000000
...