na.locf, только если другой столбец не изменился

Я уже создал несколько пользовательских настроек для zoo::na.locf, но этот сводит меня с ума. Мне нужна функция, которая будет переносить последнее наблюдение столбца, только если значения в другом столбце не изменились; и все это должно быть сгруппировано по первичному ключу. Например:

library(dplyr)
set.seed(20180409)

data <- data.frame(Id = rep(1:10, each = 24),
               Date = rep(seq.Date(as.Date("2016-01-01"), as.Date("2017-12-01"), 
                                   by = "month"), 10),
               FillCol = replace(runif(240), runif(240) < 0.9, NA),
               CheckCol = rep(letters[1:7], each = 7, length.out = 240))

data <- data %>% 
  group_by(Id) %>% 
  mutate(CheckColHasChanged = replace(lag(CheckCol) != CheckCol, 
                                      is.na(lag(CheckCol) != CheckCol), TRUE),
         FillColIsNA = is.na(FillCol))

Поэтому я пытаюсь переносить любые наблюдения FillCol, но как только мы попадем в наблюдение, где CheckColHasChanged, остановим перенос до следующего действительного наблюдения в FillCol. Я могу сделать это в цикле, но я изо всех сил пытаюсь сделать это правильно.

Fill <- TRUE #indicator for whether or not I should be carrying forward
for(row in 2:nrow(data)){

  #if the CheckCol has changed, don't fill
  if(data$CheckColHasChanged[row]){Fill <- FALSE}

  #if we should fill and still have the same Id, then fill from the last obs
  if(Fill & data$Id[row] == data$Id[row - 1]){
    data$FillCol[row] <- data$FillCol[row - 1]
  }else{ #if there's a valid obs in FillCol, set the indicator back to true
    if(!data$FillColIsNA[row]){Fill <- TRUE}
  }
}

Любая помощь будет принята с благодарностью!

1 ответ

Решение

Комментарий к ответу: это просто заполнение как Id, так и CheckCol:

data %>% group_by(Id, CheckCol) %>% 
    mutate(result = zoo::na.locf(FillCol, na.rm = FALSE))

То, как вы описываете CheckCol, это рассматривается как идентификатор. Нет разницы между "только если значения в другом столбце не изменились" и "сгруппированы по первичному ключу". У вас просто есть два столбца для группировки.

Другие вопросы по тегам