All the following require this setup:
library(zoo)
m <- matrix(c(NA, 4L, 2L, 7L, NA, 1L, NA, 2L, NA, 6L, 6L, NA, 2L, NA, 5L), 3) # input
1) I think it would be better to extend the values on the ends so with this change try the following:
tm <- t(m)
mid <- (na.locf(tm) + na.locf(tm, fromLast = TRUE))/2
t(na.fill(mid, c("extend", NA)))
giving:
[,1] [,2] [,3] [,4] [,5]
[1,] 7 7 6.5 6 2
[2,] 4 3 2.0 6 6
[3,] 2 1 3.0 3 5
By the way, note that the average of 1 and 5 is 3, not 2.
2) This is not equivalent but it may be what you really want and is short. Try linear interpoolation extending the end values:
t(na.approx(t(m), rule = 2))
giving:
[,1] [,2] [,3] [,4] [,5]
[1,] 7 7 6.500000 6.000000 2
[2,] 4 3 2.000000 6.000000 6
[3,] 2 1 2.333333 3.666667 5
3) Another possibility, again not equivalent is to replace each NA with the mean of the non-NAs on that row:
t(na.aggregate(t(m)))
giving:
[,1] [,2] [,3] [,4] [,5]
[1,] 5 7 5.000000 6.000000 2
[2,] 4 4 2.000000 6.000000 4
[3,] 2 1 2.666667 2.666667 5
4) This is a mix of (1) and (3). This fills in inner NAs with the mean of the non-NAs to either
side and fills in the end NAs with the mean of the non-NAs in that row:
tm <- t(m)
mid <- (na.locf(tm) + na.locf(tm, fromLast = TRUE))/2
ag <- na.aggregate(tm)
t(ifelse(is.na(mid), ag, mid))
giving:
[,1] [,2] [,3] [,4] [,5]
[1,] 5 7 6.5 6 2
[2,] 4 3 2.0 6 4
[3,] 2 1 3.0 3 5
Update Added more approaches and some correcetions.