Заполнение отсутствующих значений по группам в data.table
Если вы хотите заполнить отсутствующие значения переменной, основанные на предыдущем / заднем не-NA-наблюдении внутри группы, команда data.table
setkey(DT,id,date) DT[, value_filled_in := DT[!is.na(value), list(id, date, value)][DT[, list(id, date)], value, roll = TRUE]]
что довольно сложно. Это позор, так как roll
– это очень быстрый и мощный вариант (esp по сравнению с применением такой функции, как zoo::na.locf
в каждой группе)
Я могу написать функцию удобства для заполнения пропущенных значений
- Как рисовать с помощью png в качестве фона?
- экспортировать кадры данных в Excel через xlsx с условным форматированием
- распространение данных внутри вектора
- Ошибка при использовании Xcode 5.0 и Rcpp (средства командной строки ARE установлены)
- Слияние данных различных размеров
fill_na =0) c(FALSE,TRUE) else c(TRUE,FALSE)){ id <- seq_along(x) if (is.null(by)){ DT <- data.table("x" = x, "id" = id, key = "id") return(DT[!is.na(x)][DT[, list(id)], x, roll = roll, rollends = rollends, allow.cartesian = TRUE]) } else{ DT <- data.table("x" = x, "by" = by, "id" = id, key = c("by", "id")) return(DT[!is.na(x)][DT[, list(by, id)], x, roll = roll, rollends = rollends, allow.cartesian = TRUE]) } }
А потом напишите
setkey(DT,id, date) DT[, value_filled_in := fill_na(value, by = id)]
Это не очень приятно, так как хотелось бы написать
setkey(DT,id, date) DT[, value_filled_in := fill_na(value), by = id]
Однако для этого требуется огромное количество времени. И для конечного пользователя громоздко узнать, что fill_na
следует вызывать с опцией by
и не следует использовать с data.table
by
. Есть ли элегантное решение вокруг этого?
Некоторое испытание скорости
N <- 2e6 set.seed(1) DT <- data.table( date = sample(10, N, TRUE), id = sample(1e5, N, TRUE), value = sample(c(NA,1:5), N, TRUE), value2 = sample(c(NA,1:5), N, TRUE) ) setkey(DT,id,date) DT user system elapsed #> 0.086 0.006 0.105 system.time(DT[, filled1 := zoo::na.locf.default(value, na.rm = FALSE), by = id]) #> user system elapsed #> 5.235 0.016 5.274 # (lower speed and no built in option like roll=integer or roll=nearest, rollend, etc) system.time(DT[, filled2 := fill_na(value, by = id)]) #> user system elapsed #> 0.194 0.019 0.221 system.time(DT[, filled3 := fill_na(value), by = id]) #> user system elapsed #> 237.256 0.913 238.405
Почему я просто не использую na.locf.default
? Несмотря на то, что разница в скорости не очень важна, эта же проблема возникает и для других видов команд data.table (которые полагаются на слияние переменной в «by») – это позор систематически игнорировать их, чтобы получить более простой синтаксис. Мне также очень нравятся все варианты рулона.
- Должен ли я использовать data.frame или матрицу?
- может ли value.var в dcast быть списком или иметь несколько переменных значений?
- Как выровнять несколько графиков ggplot2 и добавить тени поверх них
- Пример случайных строк в каждой группе в таблице данных.
- Поиск обходного пути для файла gtable_add_grob, нарушенного ggplot 2.2.0
- удалять идентификаторы, которые встречаются x раз R
- Как организовать большие программы R?
- Почему я получаю «алгоритм не сходился» и «устанавливал prob численно 0 или 1» предупреждения с помощью glm?
Вот несколько более быстрый и компактный способ сделать это (версия 1.9.3+):
DT[, filled4 := DT[!is.na(value)][DT, value, roll = T]]