/ / Zamień NA na średnią wartości w poprzednim i następnym wierszu w R - r, replace, dataframe, na

Zamień NA na średnią wartości w poprzednim i następnym wierszu w R - r, replace, dataframe, na

Mam to dane.frame pełne NA.

DATE <- c("1","2","3","4","5","6","7","1","2","3","4","5","6","7")
COMP <- c("A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "B")
BM <- c(12,11,NA,14,NA,15,NA, 5, 5, NA, 6, NA, 8, 9)
df <- data.frame(DATE, COMP, BM, stringsAsFactors=F)

df

#    DATE COMP BM
# 1     1    A 12
# 2     2    A 11
# 3     3    A NA
# 4     4    A 14
# 5     5    A NA
# 6     6    A 15
# 7     7    A NA
# 8     1    B  5
# 9     2    B  5
# 10    3    B NA
# 11    4    B  6
# 12    5    B NA
# 13    6    B  8
# 14    7    B  9

Chcę zastąpić te NA środkami średnimiwartości w poprzednim i następnym wierszu (tylko jeśli jest to ta sama firma oczywiście) .Jeśli pierwszym wierszem jest NA, należy przyjąć następującą wartość wiersza, jeśli ostatni wiersz jest NA, drugi ostatni wiersz wartość powinna zostać pobrana.

Wynik powinien wyglądać tak

#    DATE COMP BM
# 1     1    A 12
# 2     2    A 11
# 3     3    A 12.5
# 4     4    A 14
# 5     5    A 14.5
# 6     6    A 15
# 7     7    A 15
# 8     1    B  5
# 9     2    B  5
# 10    3    B  5.5
# 11    4    B  6
# 12    5    B  7
# 13    6    B  8
# 14    7    B  9

Dziękuję Ci!

Odpowiedzi:

3 dla odpowiedzi № 1

To jest praca dla zoo:::na.approx:

library(plyr)
library(zoo)
ddply(df, .(COMP), transform, BM=na.approx(BM, rule=2))
#    DATE COMP   BM
# 1     1    A 12.0
# 2     2    A 11.0
# 3     3    A 12.5
# 4     4    A 14.0
# 5     5    A 14.5
# 6     6    A 15.0
# 7     7    A 15.0
# 8     1    B  5.0
# 9     2    B  5.0
# 10    3    B  5.5
# 11    4    B  6.0
# 12    5    B  7.0
# 13    6    B  8.0
# 14    7    B  9.0

Edytować:

W odpowiedzi na komentarz: Musisz obsługiwać sprawy z tylko jedną wartością inną niż NA lub z tylko wartości NA.

my.na.approx <- function(x) {
if (sum(is.finite(x)) == 0L) return(x)
if (sum(is.finite(x)) == 1L) return(na.approx(x, rule=2, method="constant"))
na.approx(x, rule=2)
}

my.na.approx(c(NA, 1, NA, NA, 2, NA))
#[1] 1.000000 1.000000 1.333333 1.666667 2.000000 2.000000
my.na.approx(c(NA, NA, NA, NA, 2, NA))
#[1] 2 2 2 2 2 2
my.na.approx(c(NA, NA, NA, NA, NA, NA))
#[1] NA NA NA NA NA NA