R Взвешенное скользящее среднее с частичными средними

Я пытаюсь закодировать в R (центрированную) взвешенную функцию скользящего среднего, которая возвращает мне вектор того же размера, что и входной вектор. Следующий код почти дает мне то, что я хочу, но он не работает для первого и последнего значений моего вектора

set.seed(0)
len=10
x=floor(l*runif(l))
weights=c(1,3,0,3,1)
weights=weights/sum(weights)
rollapply(x,width=length(weights), function(x) sum(x*weights),align="center")
na.omit(filter(x,sides=2,weights))

Установка частичного =TRUE в функции rollapply - это то, что я хочу сделать. В любом случае это не работает, так как моя функция не поддерживает х изменения размеров.

Я мог бы последний и вручную добавить вычисления сторон с помощью цикла. Это бы сработало, но я хотел бы найти более хороший (вычислительно более быстрый) способ сделать это.

Для более точного описания моих потребностей приведу математическую версию

r - вектор, который вернула бы моя функция

х и веса w в качестве входных данных:

1 ответ

Решение

С Rcpp вы можете сделать:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector roll_mean(const NumericVector& x,
                        const NumericVector& w) {

  int n = x.size();
  int w_size = w.size();
  int size = (w_size - 1) / 2;

  NumericVector res(n);
  int i, ind_x, ind_w;

  double w_sum = Rcpp::sum(w), tmp_wsum, tmp_xwsum, tmp_w;

  // beginning
  for (i = 0; i < size; i++) {
    tmp_xwsum = tmp_wsum = 0;
    for (ind_x = i + size, ind_w = w_size - 1; ind_x >= 0; ind_x--, ind_w--) {
      tmp_w = w[ind_w];
      tmp_wsum += tmp_w;
      tmp_xwsum += x[ind_x] * tmp_w;
    }
    res[i] = tmp_xwsum / tmp_wsum;
  }

  // middle
  int lim2 = n - size;
  for (; i < lim2; i++) {
    tmp_xwsum = 0;
    for (ind_x = i - size, ind_w = 0; ind_w < w_size; ind_x++, ind_w++) {
      tmp_xwsum += x[ind_x] * w[ind_w];
    }
    res[i] = tmp_xwsum / w_sum;
  }

  // end
  for (; i < n; i++) {
    tmp_xwsum = tmp_wsum = 0;
    for (ind_x = i - size, ind_w = 0; ind_x < n; ind_x++, ind_w++) {
      tmp_w = w[ind_w];
      tmp_wsum += tmp_w;
      tmp_xwsum += x[ind_x] * tmp_w;
    }
    res[i] = tmp_xwsum / tmp_wsum;
  }

  return res;
}

Я использую эту функцию в одном из моих пакетов.

Просто поместите это в .cpp файл и источник с Rcpp::sourceCpp,

Другие вопросы по тегам