Обновление значений столбца на основе предыдущих значений (после обработки всегда обрабатывается) - PullRequest
1 голос
/ 19 января 2020

Мне интересно, был ли гораздо более быстрый способ использования data.table / dplyr для замены значений на основе предыдущих значений на группы.

Предположим, что моя исходная таблица данных выглядит следующим образом:

DT_orig <- data.table(name = c("A", "A", "A", "B", "B", "B"), 
                      year = c("2001", "2002", "2003", "2001", "2002", "2003"),
                      treat = c(1,0,0, 0,0,1))

Это выглядит следующим образом:

 name year treat
1:    A 2001     1
2:    A 2002     0
3:    A 2003     0
4:    B 2001     0
5:    B 2002     0
6:    B 2003     1

Здесь для каждого индивидуума (имя) и периода времени (года) существует столбец (лечить), который указывает, назначен ли им курс лечения или нет.

Я рассматриваю альтернативное лечение, при котором после лечения индивида лечение остается. Таким образом, измененная таблица данных должна выглядеть следующим образом:

   name year treat
1:    A 2001     1
2:    A 2002     1
3:    A 2003     1
4:    B 2001     0
5:    B 2002     0
6:    B 2003     1

Обратите внимание, что для человека А, проходившего курс лечения в 2001 году, подразумевается, что он подвергался "лечению" и в последующие годы.

Поскольку у меня очень большая таблица данных, мне было интересно, есть ли очень быстрый способ изменить это.

Ответы [ 2 ]

4 голосов
/ 19 января 2020

Может быть, мы можем использовать cummax (из base R)

DT_orig[, treat := cummax(treat), name]
DT_orig
#   name year treat
#1:    A 2001     1
#2:    A 2002     1
#3:    A 2003     1
#4:    B 2001     0
#5:    B 2002     0
#6:    B 2003     1

Или то же самое можно сделать с dplyr

library(dplyr)
DT_orig %>%
    group_by(name) %>%
    mutate(treat = cummax(treat))

Или используя base R

DT_orig$treat <- with(DT_orig, ave(treat, name, FUN = cummax))
0 голосов
/ 20 января 2020

Я бы использовал cummax(), но есть альтернатива, иллюстрирующая синтаксис соединения data.table:

DT_orig[, year := as.integer(year)]
DT_orig[DT_orig[treat == 1], on = .(year >= year, name), treat := 1L]

   name year treat
1:    A 2001     1
2:    A 2002     1
3:    A 2003     1
4:    B 2001     0
5:    B 2002     0
6:    B 2003     1
...