我正在读取一个.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的新手,所以如果您需要更多信息,请告诉我。
提前致谢。
答案 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
。