Вычислите среднее скользящее значение с минимальным количеством значений, отличных от na, в окне перемещения

#r #mean

#r #означать

Вопрос:

Как вы можете видеть из этого примера, легко рассчитать среднее значение:

 data lt;- data.frame(dats=c(3,4,NA,4,NA,NA,6,NA,8,1,4,NA,2,NA,NA,6,NA,NA,9,5,NA,8,NA,3)) data lt;- data %gt;% mutate(rmean = caTools::runmean(dats, 3, endrule="constant"))  

Но в некоторых случаях среднее значение рассчитывается только по единственному значению no-na в данных. Как я могу предотвратить это и указать, что я получаю значение runmean только тогда, когда при расчете среднего используется определенное количество значений, отличных от na, в окне выполнения?

Ответ №1:

rmean использует NA, если не существует по крайней мере 2 NAS, не использующих rollapply, rmean2 делает это с помощью двух вызовов runmean, а rmean3-это значение, вычисленное в вопросе.

 library(zoo)  mean2 lt;- function(x) if (sum(!is.na(x)) gt;= 2) mean(x, na.rm = TRUE) else NA data %gt;%   mutate(  rmean = rollapply(dats, 3, mean2, partial = TRUE) |gt; na.fill(c("extend", NA)),  rmean2 = ifelse(runmean(!is.na(dats), 3, endrule = "constant") gt; 2/3 - 1e-5,   runmean(dats, 3, endrule = "constant"), NA),  rmean3 = runmean(dats, 3, endrule = "constant"))  

дающий:

 dats rmean rmean2 rmean3 1 3 3.500000 3.500000 3.500000 2 4 3.500000 3.500000 3.500000 3 NA 4.000000 4.000000 4.000000 4 4 NA NA 4.000000 5 NA NA NA 4.000000 6 NA NA NA 6.000000 7 6 NA NA 6.000000 8 NA 7.000000 7.000000 7.000000 9 8 4.500000 4.500000 4.500000 10 1 4.333333 4.333333 4.333333 11 4 2.500000 2.500000 2.500000 12 NA 3.000000 3.000000 3.000000 13 2 NA NA 2.000000 14 NA NA NA 2.000000 15 NA NA NA 6.000000 16 6 NA NA 6.000000 17 NA NA NA 6.000000 18 NA NA NA 9.000000 19 9 7.000000 7.000000 7.000000 20 5 7.000000 7.000000 7.000000 21 NA 6.500000 6.500000 6.500000 22 8 NA NA 8.000000 23 NA 5.500000 5.500000 5.500000 24 3 5.500000 5.500000 5.500000  

Ответ №2:

Если вы не возражаете против использования zoo библиотеки, то одним из решений было бы определить пользовательскую функцию:

 rolling_mean = function(x) {   ifelse(length(na.omit(x)) gt; 2, mean(x), "too_many_missing") }  

Затем переверните набор данных, используя rollapply :

 library(zoo) library(dplyr) data %gt;%   mutate(remean = rollapply(dats, width=3, FUN=rolling_mean, partial = 2)) %gt;%  na.fill(c("extend", NA))  

Конечно, вы можете изменить значение в пользовательской функции, чтобы изменить количество не NA -значений.

Кроме того, вы, вероятно, захотите изменить "too_many_missing" строку на NA , чтобы избежать приведения всего столбца к символьной переменной.

 dats remean 1 3 lt;NAgt; 2 4 too_many_missing 3 NA too_many_missing 4 4 too_many_missing 5 NA too_many_missing 6 NA too_many_missing 7 6 too_many_missing 8 NA too_many_missing 9 8 too_many_missing 10 1 4.33333333333333 11 4 too_many_missing 12 NA too_many_missing 13 2 too_many_missing 14 NA too_many_missing 15 NA too_many_missing 16 6 too_many_missing 17 NA too_many_missing 18 NA too_many_missing 19 9 too_many_missing 20 5 too_many_missing 21 NA too_many_missing 22 8 too_many_missing 23 NA too_many_missing 24 3 lt;NAgt;   

Комментарии:

1. Предложите использовать NA вместо символьной строки, чтобы результат оставался числовым. Также используйте na.fill(rollapply(…), c(«расширить», NA)), чтобы продлить первый и последний не-NA до конца.