Suppose we have DF
shown in the Note. Then assuming that you want to replace NAs with a linear interpolation of the nearest non-NAs and simply extend non-NAs to fill in values at the beginning and end:
library(zoo)
replace(DF, 2:3, na.approx(DF[-1], rule = 2))
giving:
## V1 V2 V3
## 1 A 1.000000 1.0
## 2 B 1.000000 1.5
## 3 C 1.333333 2.0
## 4 D 1.666667 3.0
## 5 E 2.000000 3.5
## 6 F 2.333333 4.0
## 7 G 2.666667 5.0
## 8 H 3.000000 5.0
If you want the average of the nearest NAs then use na.locf
both forward and backward and then average them and finally fill in the extremities using na.fill
.
library(zoo)
replace(DF, 2:3, na.fill(
(na.locf(DF[-1], na.rm = FALSE) +
na.locf(DF[-1], fromLast = TRUE, na.rm = FALSE))/2,
"extend"))
## V1 V2 V3
## 1 A 1.0 1.0
## 2 B 1.0 1.5
## 3 C 1.5 2.0
## 4 D 1.5 3.0
## 5 E 2.0 3.5
## 6 F 2.5 4.0
## 7 G 2.5 5.0
## 8 H 3.0 5.0
Yet another approach is to use splines. See ?na.spline
.
Note
DF <- data.frame(V1 = head(LETTERS, 8), V2 = c(NA, 1, NA, NA, 2, NA, NA, 3),
V3 = c(1, NA, 2, 3, NA, 4, 5, NA))