我正在尝试更换NA&零值递归。我正在处理时间序列数据,其中NA或零最好用前一周的值替换(每15分钟测量一次,因此返回672步)。我的数据包含〜两年15分钟值的数据,因此这是一个大集合。预期不会有太多的NA或零,并且也不期望相邻的零序列或NA> 672。
我发现这个线程(recursive replacement in R)显示了递归方式,并根据我的问题进行了调整。
load[is.na(load)] <- 0
o <- rle(load)
o$values[o$values == 0] <- o$values[which(o$values == 0) - 672]
newload<-inverse.rle(o)
现在这是“最好的”还是优雅的方法? 如果在前672个值中出现零值,我将如何保护代码免受错误的影响?
我习惯了matlab,我会做类似的事情:
% Replace NaN with 0
Load(isnan(Load))=0;
% Find zero values
Ind=find(Load==0);
for f=Ind
if f>672
fprintf('Replacing index %d with the load 1 day ago\n', Ind)
% Replace zero with previous week value
Load(f)=Load(f-672);
end
end
由于我不熟悉R如何设置这样的if else循环?
一个可重现的示例(将代码更改为其他线程使用的示例并未处理相邻的零):
day<-1:24
load<-rep(day, times=10)
load[50:54]<-0
load[112:115]<-NA
load[is.na(load)] <- 0
load[load==0]<-load[which(load == 0) - 24]
这给出了没有零和NA的原始加载数据帧。 如果在前24个值中存在零,则会出错,因为没有值可以替换为:
loadtest[c(10,50:54)]<-0 # instead of load[50:54]<-0 gives:
Error in loadtest[which(loadtest == 0) - 24] :
only 0's may be mixed with negative subscripts
现在要解决这个问题,可以使用if else语句,但我不知道如何申请。类似的东西:
day<-1:24
loadtest<-rep(day, times=10)
loadtest[c(10,50:54)]<-0
loadtest[112:115]<-NA
loadtest[is.na(loadtest)] <- 0
if(INDEX(loadtest[loadtest==0])<24) {
# nothing / mean / standard value
} else {
loadtest[loadtest==0]<-loadtest[which(loadtest == 0) - 24]
}
Ofcourse INDEX不是有效代码..
答案 0 :(得分:1)
您可以使用此示例:
set.seed(42)
x <- sample(c(0,1,2,3,NA), 100, T)
stepback <- 6
x_old <- x
x_new <- x_old
repeat{
filter <- x_new==0 | is.na(x_new)
x_new[filter] <- c(rep(NA, stepback), head(x_new, -stepback))[filter]
if(identical(x_old,x_new)) break
x_old <- x_new
}
x
x_new
结果:
> x
[1] NA NA 1 NA 3 2 3 0 3 3 2 3 NA 1 2 NA NA 0 2 2 NA 0 NA NA 0
[26] 2 1 NA 2 NA 3 NA 1 3 0 NA 0 1 NA 3 1 2 0 NA 2 NA NA 3 NA 3
[51] 1 1 1 3 0 3 3 0 1 2 3 NA 3 2 NA 0 1 NA 3 1 0 0 1 2 0
[76] 3 0 1 2 0 2 0 1 3 3 2 1 0 0 1 3 0 1 NA NA 3 1 2 3 3
> x_new
[1] NA NA 1 NA 3 2 3 NA 3 3 2 3 3 1 2 3 2 3 2 2 2 3 2 3 2
[26] 2 1 3 2 3 3 2 1 3 2 3 3 1 1 3 1 2 3 1 2 3 1 3 3 3
[51] 1 1 1 3 3 3 3 1 1 2 3 3 3 2 1 2 1 3 3 1 1 2 1 2 3
[76] 3 1 1 2 2 2 3 1 3 3 2 1 3 1 1 3 2 1 3 1 3 1 2 3 3
请注意,某些值仍为NA
,因为没有先前的信息可用于它们。如果您的数据有足够的先验信息,则不会发生这种情况。
答案 1 :(得分:1)
一种选择是将矢量包装成一个包含672行的矩阵:
load2 <- matrix(load, nrow=672)
然后将最后一个观察结果(从动物园或上面的方法,或......)应用到矩阵的每一行:
load3 <- apply( load2, 1, locf.function )
然后将得到的矩阵带回到具有正确长度的向量:
load4 <- t(load3)[ seq_along(load) ]