Векторизованная взвешенная арифметика через матрицу - PullRequest
0 голосов
/ 04 февраля 2019

Мне было интересно, есть ли способ векторизовать взвешенную арифметику через матрицы.например, для вычисления взвешенного среднего значения values ниже заданного weights:

set.seed(12321)
values = matrix(sample(10:40, 6, replace = TRUE), ncol = 2)
weights = matrix(sample(1:5, 6, replace = TRUE), ncol = 2)

Мы можем сделать:

w.mean = numeric()

for (i in 1:dim(values)[1]){
  w.mean[i] = stats::weighted.mean(x=values[i,], w =  weights[i,])
}

Но это не быстро для больших матриц.Мне было интересно, есть ли полностью векторизованный способ с использованием семейства apply или aggregate или аналогичного.

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Спасибо всем.Действительно проницательные ответы.Я проверил их, и sapply оказался быстрым, а после этого abind.Однако в моем исходном наборе данных у меня были группировки, которые я суммировал по группам, используя dcast.Однако после того, как я увидел предложение для ddply, я вернулся к нему.Я понял, что использование data.table делает его на несколько порядков быстрее: действительно,

n = 1000
DT = data.table(id = sample(LETTERS[1:10], size = n, replace = TRUE),
                value = sample(seq(20,30), size = n, replace = TRUE),
                weight = sample(seq(1,5), size = n, replace = TRUE))

wtd_var = DT[,lapply(.SD,function(x)(weightedVar(as.numeric(x),w=weight))),by=id,.SDcols='value']
wtd_var

data.table s рок!

0 голосов
/ 04 февраля 2019

вы можете попробовать сгруппировать ваши значения и веса в один data.frame

value_weight <- data.frame(group = rep(1:2, each = 3), 
                           value = sample(10:40, 6, replace = TRUE), 
                           weight = sample(1:5, 6, replace = TRUE))

, а затем использовать plyr библиотеку

ddply(value_weight, .(group), # split the data frame according to group
      function(x) data.frame(wret = weighted.mean(x$value, x$weight)))

дополнительную информацию здесь

...