如何根据之前和之后的值替换“NA”

时间:2014-01-24 21:11:07

标签: r dataset dataframe

我正在读取一个.csv,其中包含一系列匹配数字的列,其中包含NA。我想用系列外部的数字替换NAs,以便制作一系列匹配数字。

我想转此:

df <- data.frame(col1 = c(1,NA,NA,NA,1,2,NA,NA,NA,NA,2,NA,3,NA,NA,3))
#into this
df2 <- data.frame(col1 = c(1,1,1,1,1,2,2,2,2,2,2,NA,3,3,3,3))

我试图找到一种方法来做到这一点,但我所有的搜索都让我感到无助。

我仍然是R的新手,所以如果您需要更多信息,请告诉我。

提前致谢。

3 个答案:

答案 0 :(得分:2)

试试这个:

library(zoo)

a0 <- na.locf(df$col1)
a1 <- na.approx(df$col1)

df2 <- transform(df, col1 = ifelse(a0 == a1, a0, NA))

给出:

> df2
   col1
1     1
2     1
3     1
4     1
5     1
6     2
7     2
8     2
9     2
10    2
11    2
12   NA
13    3
14    3
15    3
16    3

修订:做了一些改进。

答案 1 :(得分:1)

您可以在zoo包中使用na.approx为您提供线性插值:

df <- data.frame(col1 = c(1,NA,NA,NA,1,2,NA,NA,NA,NA,2,NA,3,NA,NA,3))
require(zoo)
outVec = na.approx(df$col, na.rm=F)

正如RoyalTS的评论中提到的那样,用2.5替换2和3之间的NA。

如果您不想插值并知道该数字不重叠(例如没有c(1,NA,NA,2,NA,NA,1,NA,2)),您可以执行foreach循环:

df <- data.frame(col1 = c(1,NA,NA,NA,1,2,NA,NA,NA,NA,2,NA,3,NA,NA,3))
tt=unique(df$col1); tt=tt[!is.na(tt)]
require(foreach)
foreach(num = tt) %do%
{ df$col1[min(which(df$col1==num)):max(which(df$col1==num))] = num  }
print(df)

答案 2 :(得分:1)

rle再次救援。

Rgames> foo<-unlist(df)
Rgames> foo[is.na(foo)]<- -1 # I'm assuming you have no "-1" in your data. Pick a nonvalid number
Rgames> bar<-rle(foo)
Rgames> for(j in 2:9) if(bar$values[j-1]==bar$values[j+1]&bar$values[j-1]!=-1) bar$values[j]<-bar$values[j-1]
Rgames> oof<-inverse.rle(bar)
Rgames> oof
 [1]  1  1  1  1  1  2  2  2  2  2  2 -1  3  3  3  3

然后,如果需要,请将所有-1替换为NA