Интерполировать NA в R с последним или следующим наблюдением по наименьшему интервалу - PullRequest
0 голосов
/ 13 апреля 2020

Я хотел бы рассчитать пропущенные значения, используя последнее наблюдение, перенесенное вперед (locf), или следующее наблюдение, перенесенное назад (nocb) в два или более промежутка.

Для определения направления (сверху / вниз) ), чтобы заполнить пропущенные значения, первый столбец (интервал) в кадре данных взвешивается. Интерполяция (locf / nocb) должна начинаться с конца с наименьшим значением (значения интервала, соответствующие строкам NA наружу). Заполнением по умолчанию является locf.

Пример: logi c для исключительного nafill: в столбце ID2, строка 5-7 (заголовок включен), направление будет nocb, потому что (Interval [7,] value = 50) ), который меньше значения интервала [5,] = 100.

Попытка использовать df1 <-df %>%fill(ID1, ID2, ID3,which.min(Interval)) %>% #default direction down fill(ID1, ID2, ID3, .direction = "up",which.min(Interval)) не работает, пожалуйста, помогите исправить ее или предложите другое эффективное решение R. Спасибо заранее за вашу помощь.

Ввод

df = data.frame(
             Interval = c(0,20,80,100,50,50,130,100,70,80,200), 
             ID1 = c(0,1,1,0,NA,NA,NA,NA,1,NA,1), 
             ID2 = c(1,0,0,NA,NA,NA,1,1,3,NA,1), 
             ID3 = c(1,NA,1,0,3,NA,NA,NA,1,NA,1) 
)

Interval    ID1 ID2 ID3
0   0   1   1
20  1   0   NA
80  1   0   1
100 0   NA  0
50  NA  NA  3
50  NA  NA  NA
130 NA  1   NA
100 NA  1   NA
70  1   3   1
80  NA  NA  NA
200 1   1   1

Ожидаемый результат

Interval    ID1 ID2 ID3
0   0   1   1
20  1   0   NA
80  1   0   1
100 0   1   0
50  0   1   3
50  0   1   3
130 0   1   3
100 0   1   3
70  1   3   1
80  NA  NA  NA
200 1   1   1

1 Ответ

0 голосов
/ 13 апреля 2020

Не ясно, для чего предназначен ваш первый столбец. Ваш второй ожидаемый столбец представляет собой смесь locf и nocb, однако вы можете использовать стандартный nafill столбец за столбцом:

library(data.table)
apply(df, 2, function(j) {nafill(j, type = "locf")})

Согласно вашему комментарию, если вы хотите сделать nafill в зависимости от df$Interval вы можете индексировать df, используя:

StartIndex <- apply(df[,2:dim(df)[2]], 2, function(j) {
  which(diff(is.na(j)) == 1 ) + 1})
EndIndex <- apply(df[,2:dim(df)[2]], 2, function(j) {
  which(diff(is.na(j)) == -1) })

И указав, увеличивается или уменьшается начало и конец df$Interval:

lapply(1:(dim(df)[2]-1), function(i) {
  lapply(1:length(StartIndex[[i]]), function(j) {
    range <- c(StartIndex[[i]][j], EndIndex[[i]][j])
    if (range[1] != range[2]) {
      df$Interval[range[1]] - df$Interval[range[2]]
    }
  })
})
...