#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])))