R Перенести последнее наблюдение вперед n раз

Я пытаюсь перенести неотмеченные наблюдения вперед и заполнить следующие два отсутствующих наблюдения (хотя я полагаю, что решение этой проблемы было бы широко применимо для переноса наблюдений вперед через n строк ...).

В приведенном ниже примере кадра данных я хотел бы перенести (распространить) значения flag_a и flag_b для каждого id для двух строк. Вот пример моих данных с включенным желаемым результатом:

id <- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2)
flag_a <- as.numeric(c(NA, NA, 1, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA, NA, NA, NA,   NA, NA))
flag_b <- as.numeric(c(NA, NA, NA, 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA, NA, NA, NA))
flag_a_desired_output <- as.numeric(c(NA, NA, 1, 1, 1, NA, NA, NA, NA, NA, NA, 1, 1, 1, NA, NA, NA, NA))
flag_b_desired_output <- as.numeric(c(NA, NA, NA, 1, 1, 1, NA, NA, NA, NA, NA, NA, NA, 1, 1, 1, NA, NA))
data <- data.frame(cbind(id, flag_a, flag_b, flag_a_desired_output, flag_b_desired_output))

Я попытался использовать следующую функцию переноса последнего наблюдения (LOCF); однако, как и ожидалось, он заполняет все отсутствующие строки, а не только следующие две.

na.locf.na <- function(x, na.rm = FALSE, ...) na.locf(x, na.rm = na.rm, ...)
data <- transform(data, flag_a_locf = ave(flag_a, id, FUN = na.locf.na))
data <- transform(data, flag_b_locf = ave(flag_b, id, FUN = na.locf.na))

Будем очень признательны за любые мысли о том, как это сделать.


person Entropy    schedule 06.06.2014    source источник
comment
Для чего id? Это имеет отношение к вашей проблеме?   -  person Rich Scriven    schedule 07.06.2014
comment
id - это идентификатор для каждого уникального объекта, содержащегося в общем наборе данных. Причина, по которой я включил его сюда, заключается в том, что если flag_a должен был появиться только на одну строку до конца строк, связанных с этим id, тогда я бы не хотел, чтобы код переносил наблюдение из id == 1 вперед в первую строку, где id == 2. Имеет ли это смысл?   -  person Entropy    schedule 07.06.2014


Ответы (2)


Это не самое красивое, но вот как я справляюсь с такими проблемами:

library(data.table)
data <- data.table(data)
data[, rowid:=1:.N, keyby = id]

## flag_a
data[, flag_a_min:=min(rowid[!is.na(flag_a)]), keyby = id]
data[, flag_a_max:=flag_a_min+2]
data[rowid <=flag_a_max & rowid >= flag_a_min, flag_a:=min(na.omit(flag_a))]

## flag_b
data[, flag_b_min:=min(rowid[!is.na(flag_b)]), keyby = id]
data[, flag_b_max:=flag_b_min+2]
data[rowid <=flag_b_max & rowid >= flag_b_min, flag_b:=min(na.omit(flag_b))]

## clean up
data[, c("rowid", "flag_a_min", "flag_a_max", "flag_b_min", "flag_b_max"):=NULL]

> data
    id flag_a flag_b flag_a_desired_output flag_b_desired_output
 1:  1     NA     NA                    NA                    NA
 2:  1     NA     NA                    NA                    NA
 3:  1      1     NA                     1                    NA
 4:  1      1      1                     1                     1
 5:  1      1      1                     1                     1
 6:  1     NA      1                    NA                     1
 7:  1     NA     NA                    NA                    NA
 8:  1     NA     NA                    NA                    NA
 9:  1     NA     NA                    NA                    NA
10:  1     NA     NA                    NA                    NA
11:  2     NA     NA                    NA                    NA
12:  2      1     NA                     1                    NA
13:  2      1     NA                     1                    NA
14:  2      1      1                     1                     1
15:  2     NA      1                    NA                     1
16:  2     NA      1                    NA                     1
17:  2     NA     NA                    NA                    NA
18:  2     NA     NA                    NA                    NA
person Fojtasek    schedule 06.06.2014

Вы можете использовать параметр maxgap для na.locf в пакете imputeTS, чтобы только вменять / заполнять пробелы NA меньше определенного размера. (это решение оставит нетронутыми более длинные промежутки NA)

e.g.

library(imputeTS)
na_locf(input, maxgap = 2)

будет применять только перенесенное вперед последнее наблюдение (locf) к пропускам NA, которые меньше 2 последовательных NA.

2,3,NA,NA,NA,5,5 просто останется 2,3,NA,NA,NA,5,5

в то время как

2,3,NA,5,5,5,5 станет 2,3,3,5,5,5,5

person Steffen Moritz    schedule 07.10.2019