Заполнение пропущенных значений

Dec 18, 2018 14:57

Здравствуйте ( Read more... )

Leave a comment

Comments 9

jzha December 18 2018, 21:01:11 UTC
Здравствуйте.
Можно посчитать число строк с NA значениями, следующих за каждой строкой без пропущенных значений. Затем размножить известные строки с требуемой кратностью.

library(data.table)

modify_DT <- function(dat){
# находим индексы валидных строк
valuesIdx <- which(!is.na(dat[, b]))
# берем валидные строки, за исключением столбца а, и добавляем столбец с кратностями
out <- cbind(dat[valuesIdx, !('a')], times = c(valuesIdx[-1], dat[, .N] + 1) - valuesIdx)
# тиражируем строки
out <- out[rep.int(1:.N, times)]
# удаляем столбец times и вставляем исходный столбец а
out[, c('times', 'a') := list(NULL, dat[,a])]
# возвращаем требуемую таблицу с исходным порядком столбцов
setcolorder(out, 'a')[]
}

Reply

jzha December 18 2018, 21:21:21 UTC
Это решение на произвольное число столбцов, при условии, что первая строка таблицы без пропущенных значений. Имя столбца без пропущенных значений --- 'а', и в таблице есть столбец с именем 'b'.

Tibble решение, приведенное выше, гораздо эффективнее цикла. Но data.table в данном примере работает на порядка быстрее tibble.

modify_TBL <- function(dat){
dat %>%
mutate(flag = as.integer(!is.na(c)),
cs = cumsum(flag)) %>%
group_by(cs) %>%
mutate(b = first(b),
c = first(c)) %>%
ungroup() %>%
select(-flag, -cs)
}

Задаем таблицу

set.seed(123)
n <- 1e6
dat <- data.table(a = sample.int(10, n, replace = T),
b = sample(c(NA, 1:10), n, replace = T, prob = c(0.8, rep(0.02, 10))))
dat[, c := as.integer((b + 5) %% 10)]
dat[1, c('b', 'c') := 2L]

Преобразуем ее в tibble. Убеждаемся, что результаты совпадают

tbl <- as.tibble(dat)
all.equal(as.tibble(modify_DT(dat)), modify_TBL(tbl))

Медианное время 34 и 667 milliseconds

microbenchmark(modify_DT(dat), modify_TBL(tbl), times = 10)

Reply

ittei December 19 2018, 07:25:59 UTC
Огромное спасибо!
Очень изящно!
Количество столбцов плавает, поэтому первое решение - то что надо.
Тем более попробовал то что сам предложил, до конца расчета ждать не стал.

Reply


Leave a comment

Up