Эти проблемы похожи на эту мою тему
расчет 90 процентиля и замена его медианой по группам в R
С этим различием, что.
Но в этой теме
Обратите внимание, что вычисление выполняется с помощью 14 нулей, предшествующих одной категории действия, но замена на медиану выполняется для всех нулевых категорий действия и выполнения для каждой группы код + элемент
, а именно, теперь я использую все нули, а не 14 предшествующих, и не касаюсь отрицательных и нулевых значений возврата.
По групповой переменной (action- 0, 1) для категории Zero
, я хочу найти 75 процентиль по возвращаемой переменной, и если значение больше 75 процентили, оно должно быть заменено на медиану категорией zero
. Таким образом, есть переменная code
Эта процедура должна быть выполнена для кода отдельно. Примечание: отрицательное и нулевое значение я не касаюсь
mydat=structure(list(code = c(123L, 123L, 123L, 123L, 123L, 123L, 123L,
123L, 123L, 123L, 123L, 123L, 124L, 124L, 124L, 124L, 124L, 124L,
124L, 124L, 124L, 124L, 124L, 124L), action = c(0L, 0L, 0L, 0L,
0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L,
1L, 1L, 1L, 1L), return = c(-1L, 0L, 23L, 100L, 18L, 15L, -1L,
0L, 23L, 100L, 18L, 15L, -1L, 0L, 23L, 100L, 18L, 15L, -1L, 0L,
23L, 100L, 18L, 15L)), .Names = c("code", "action", "return"), class = "data.frame", row.names = c(NA,
-24L))
\
23
100
18
15
Как это сделать, чтобы получить этот вывод. итак 75 процентиль:
42,25
Медиана = 20,5, замена
add action return
123 0 -1
123 0 0
123 0 23
123 0 ***20,5
123 0 18
123 0 15
123 1 -1
123 1 0
123 1 23
123 1 100
123 1 18
123 1 15
124 0 -1
124 0 0
124 0 23
124 0 ***20,5
124 0 18
124 0 15
124 1 -1
124 1 0
124 1 23
124 1 100
124 1 18
124 1 15
Используя лучшее решение Uwe, я получаю ошибку
Error in `[.data.table`(mydat[action == 0, `:=`(output, as.double(return))], :
Column(s) [action] not found in i
Как сделать это отрицательное и нулевое значение, которого я не касаюсь, и почему произошла эта ошибка.
library(data.table)
# mark the zero acton rows before the the action period
setDT(mydat)[, zero_before := cummax(action), by = .(code)]
# compute median and 90% quantile for that last 14 rows before each action period
agg <- mydat[zero_before == 0,
quantile(tail(return), c(0.5, 0.75)) %>%
as.list() %>%
set_names(c("med", "q90")) %>%
c(.(zero_before = 0)), by = .(code)]
agg
# append output column
mydat[action == 0, output := as.double(return)][
# replace output values greater q90 in an update non-equi join
agg, on = .(code,action, return > q90), output := as.double(med)][
# remove helper column
, zero_before := NULL]