Как рассчитать совокупное среднее значение блока фрейма данных до каждой строки в R

#r #dataframe

Вопрос:

У меня есть упрощенный фрейм данных, который выглядит следующим образом:

 df
volume ask1 ask2 bid1 bid2
0      38   NA   38   37.9
100    38.1 38.2 37.8 38.2
0      38.4 38.5 38.2 38.3
0      38.4 38.5 38.2 NA
200    38.3 38.1 38   38.4
250    38.4 38.2 NA   38.6
 

Я хочу иметь еще один столбец, который содержит среднее значение df[1:i, 2:5] в i й строке.

Я могу сделать это с помощью цикла for:

 df[, "midpoint"] <- NA
for (i in 1:nrow(df)) {
   df$midpoint[i] <- mean(as.matrix(df[c(1:i), c(2:5)]), na.rm = TRUE)
}
 

Но поскольку мой фрейм данных на самом деле большой, цикл for занимает много времени.

Я пытался sapply , но потерпел неудачу:

 df[, "midpoint"] <- sapply(df, function(i) mean(as.matrix(df[c(1:i), c(2:5)]), na.rm = TRUE))
 

Кто-нибудь может дать мне несколько советов?

Ответ №1:

С sapply вами можно сделать :

 mat <- as.matrix(df[, 2:5])
df$midpoint <- sapply(seq(nrow(df)), function(i) mean(mat[1:i, ], na.rm = TRUE))
 

Вы также можете использовать средства, которые будут быстрее, но приведут к небольшой ошибке.

 library(dplyr)
df %>%
  mutate(res = rowMeans(select(., 2:5), na.rm = TRUE), 
         res = cummean(res))

#  volume ask1 ask2 bid1 bid2 midpoint      res
#1      0 38.0   NA 38.0 37.9 37.96667 37.96667
#2    100 38.1 38.2 37.8 38.2 38.02857 38.02083
#3      0 38.4 38.5 38.2 38.3 38.14545 38.13056
#4      0 38.4 38.5 38.2   NA 38.19286 38.18958
#5    200 38.3 38.1 38.0 38.4 38.19444 38.19167
#6    250 38.4 38.2   NA 38.6 38.22381 38.22639
 

Вот midpoint фактический ответ из цикла или sapply кода for и res ответ из приведенного выше расчета.

Ответ №2:

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

Попробуй

 sapply(1:nrow(df), function(x) mean(as.matrix(df)[x, 2:5], na.rm = TRUE))
 

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

1. каким-то образом это дает мне это предупреждение: In mean.default(as.matrix(df)[x, 2:5], na.rm = TRUE) : argument is not numeric or logical: returning NA я пытаюсь понять, что произошло.

2. Это указывает на то, что некоторый вектор столбцов в ваших данных не является числовым.

3. ДА. Некоторые из них являются NA s. Но я думаю na.rm = TRUE , что должен выполнить эту работу..

4. Нет, NA буквы » с » — это не проблема. Некоторые из них могут быть character или factor .

Ответ №3:

 rowSums(cumsum(df[2:5]), na.rm=T) / cumsum(rowSums(!is.na(df[2:5])))