добавление отсутствующих данных на основе среднего значения до и после записи - PullRequest
0 голосов
/ 28 октября 2019

Отсутствующие данные столбца WT кодируются как -99. Я хочу заменить отсутствующие значения на среднее значение предыдущего и следующего значения WT.

Например, отсутствующие значения имеют время = 2 и время = 3. Я хочу вычислить Time1 + Time4 / 2 и добавить его как для time = 2, так и для time = 3, т.е. 5.5 будет добавлено для обоих Time =2 и 3. Он должен быть одинаковым для всех пропущенных значений.

ID  TIME    WT
1   0   4
1   1   5
1   2   -99
1   3   -99
1   4   6
1   5   9
1   6   12
1   7   -99
1   8   -99
1   9   -99
1   10  -99
1   12  16
1   14  18
1   16  20

Ответы [ 2 ]

0 голосов
/ 28 октября 2019

Вот иллюстрация моего комментария в качестве ответа:

library(readr)
library(zoo)

df <- read_table("ID TIME WT
1   0   4
1   1   5
1   2   -99
1   3   -99
1   4   6
1   5   9
1   6   12
1   7   -99
1   8   -99
1   9   -99
1   10  -99
1   12  16
1   14  18
1   16  20")

df$WT[df$WT ==-99]<- NA
na.approx(df$WT, method = "constant", rule = 2, f = 0.5)

Вывод:

[1]  4.0  5.0  5.5  5.5  6.0  9.0 12.0 14.0 14.0 14.0 14.0 16.0 18.0 20.0
0 голосов
/ 28 октября 2019

Я добавил пропущенные значения в первую и последнюю строки для тестирования:

data <- data.frame(ID=1,TIME=0:16,WT=4:20)
data[c(1,3,4,8,9,10,11,16,17),"WT"] <- -99

Несколько нелегкий подход, но вы могли бы сначала попытаться разобраться с возможностью пропустить первое и последнее значения:

data$WT[data$WT == -99] <- NA
missing <- which(is.na(data$WT))

if(1 %in% missing){
  data$WT[1] <- head(data$WT[!is.na(data$WT)],1)
}
if(nrow(data) %in% missing){
  data$WT[nrow(data)] <- tail(data$WT[!is.na(data$WT)],1)
}

Затем вы можете найти начало и конец каждого прогона NA с помощью этой функции:

get_runs <- function(x){
  starts <- which(diff(x) == 1)
  y <- rle(x)
  len <- y$lengths[y$values==TRUE]
  ends <- starts + len+1
  return(list(starts=starts,len=len,ends=ends, i=1:length(starts)))
}

r <- get_runs(is.na(data$WT))

Наконец, пропустите пропущенные значения и заполните их:

for(i in r$i){
  idx <- seq(r$starts[i]+1,r$ends[i]-1,1)
  data$WT[idx] <- (data$WT[r$starts[i]] + data$WT[r$ends[i]])/2
}

data
   ID TIME   WT
1   1    0  5.0
2   1    1  5.0
3   1    2  6.5
4   1    3  6.5
5   1    4  8.0
6   1    5  9.0
7   1    6 10.0
8   1    7 12.5
9   1    8 12.5
10  1    9 12.5
11  1   10 12.5
12  1   11 15.0
13  1   12 16.0
14  1   13 17.0
15  1   14 18.0
16  1   15 18.0
17  1   16 18.0
...