将NA替换为NA之前和之后的平均值,除非行以NA开始或结束

时间:2017-10-13 10:00:09

标签: r replace interpolation

说我有一个data.frame:

t<-c(1,1,2,4,NA,3) 
u<-c(1,3,4,6,4,2)
v<-c(2,3,4,NA,3,2)
w<-c(2,3,4,5,2,3)
x<-c(2,3,4,5,6,NA)
df<-data.frame(t,u,v,w,x)
df

   t u  v w  x
1  1 1  2 2  2
2  1 3  3 3  3
3  2 4  4 4  4
4  4 6 NA 5  5
5 NA 4  3 2  6
6  3 2  2 3 NA

我想更改NA,以便NA被NA之前的一个值和NA之后的一个值的平均值替换。但是,如果一行以NA开头,我希望它被后面的值替换。当一行以NA结尾时,我希望它被NA之前的值替换。因此,我想得到以下结果:

   t u  v   w  x
1  1 1  2   2  2
2  1 3  3   3  3
3  2 4  4   4  4
4  4 6  5.5 5  5    --> NA becomes average of 6 and 5
5  4 4  3   2  6    --> NA becomes value of next case  
6  3 2  2   3  3    --> NA becomes value of previous case

我有数千行,所以非常感谢任何帮助!

4 个答案:

答案 0 :(得分:0)

始终在您使用的函数中搜索参数na.rm = T. 在这种情况下,您希望使用其中一个列的平均值,并将na.rm参数设置为true。 那么你想用NA-s代替。

dt[is.na(dt[,'t']),'t'] = 0

(假设我没有颠倒维度的顺序)

答案 1 :(得分:0)

这是一个可能的解决方案,

如果NA替换为(滞后+超前)/ 2,如果NA仍然用NA代替铅,则替换为滞后。

library(dplyr)
t(apply(df, 1, function(x){
     lagx = dplyr::lag(x)
     leadx = dplyr::lead(x)
     b = ifelse(is.na(x),(leadx+lagx)/2, x)
     b = ifelse(is.na(b), leadx, b)
     b = ifelse(is.na(b), lagx, b)
     return(b)
     }
))
#output
     t u   v w x
[1,] 1 1 2.0 2 2
[2,] 1 3 3.0 3 3
[3,] 2 4 4.0 4 4
[4,] 4 6 5.5 5 5
[5,] 4 4 3.0 2 6
[6,] 3 2 2.0 3 3

答案 2 :(得分:0)

根据之前的na.approx解决方案,这可能会解决问题:

library(zoo)
t(apply(df, 1,function(x) na.approx(x,rule=2)))

答案 3 :(得分:0)

t<-c(1,1,2,4,NA,3) 
u<-c(1,3,4,6,4,2)
v<-c(2,3,4,NA,3,2)
w<-c(2,3,4,5,2,3)
x<-c(2,3,4,5,6,NA)
df<-data.frame(t,u,v,w,x)

df[which(is.na(t)), "t"] <- df[which(is.na(t)), "u"]
df[which(is.na(x)), "x"] <- df[which(is.na(x)), "w"]
df[which(is.na(v)), "v"] <- (df[which(is.na(v)), "u"] + df[which(is.na(v)), "w"])/2

> df
  t u   v w x
1 1 1 2.0 2 2
2 1 3 3.0 3 3
3 2 4 4.0 4 4
4 4 6 5.5 5 5
5 4 4 3.0 2 6
6 3 2 2.0 3 3