如何根据下一个实际值填写 NA 值,但将该值除以前面的 NA?

How can I fill in NA values based on the next real value but divide that value between the preceding NAs?

请注意:这是对 'data' 来源的超简化解释,但数据来源与编码问题无关。

我有一个数据集,是通过每天在试管中收集水而创建的。 我不能每天去测量管子(但管子一直充满)所以水值记录中存在空白。 这个虚拟数据集显示了第 5 天和第 10 天发生这种情况的位置,因为这是一个虚拟数据集,我假设每天有 500 毫升水进入试管(真实数据集更加混乱!)

虚拟数据

day<-c(1,2,3,4,5,6,7,8,9,10,11,12)
value<-c(500,500,500,500,NA,1000,NA,NA,NA,2000,500,500)
df<-data.frame(day,value)

数据说明:我每天都采集了几天1:4所以每天的值是500ml,错过了第5天所以值是NA,第6天采集所以值是1000ml(水从第 5 天和第 6 天合并),错过了 7、8、9,所以值等于 NA,在第 10 天收集,4 天的值为 2000ml)然后在最后两天每天收集)

我想通过获取下一个 'real' 测量值并将该值除以 NA 和该值 day.Yes 来填补 NA 空白,我假设如果我有没有进行测量有一个恒定的过程,我可以在几天之间平分最后一次测量。

这是输出数据的样子

day<-c(1,2,3,4,5,6,7,8,9,10,11,12)
corrected.value<-c(500,500,500,500,500,500,500,500,500,500,500,500)
corrected.df<-data.frame(day,corrected.value)

同样,这只是一个虚拟数据集,否则最简单的方法就是用“value[is.na(value)] <- 500”将 NA 替换为 500,但在真实数据集中,这些值可以是 457.6、779、376 等. 还尝试做一个循环,但一直卡住...... 关于如何执行此操作的任何想法?

非常感谢帮助

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

# Create test Data: 
# note that this is slightly different from your input
# but in this way you can better verify that it works as expected
day<-c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
value<-c(NA,500,500,500,NA,3000,NA,NA,NA,5000,500,500,NA,NA,NA)
df<-data.frame(day,value)


# "Cleansing" starts here :
RLE <- rle(is.na(df$value))

# we cannot do anything if last values are NAs, we'll just keep them in the data.frame
if(tail(RLE$values,1)){
  RLE$lengths <- head(RLE$lengths,-1)
  RLE$values <- head(RLE$values,-1)
}

afterNA <- cumsum(RLE$lengths)[RLE$values] + 1
firstNA <- (cumsum(RLE$lengths)- RLE$lengths + 1)[RLE$values]
occurences <- afterNA - firstNA + 1
replacements <- df$value[afterNA] / occurences

df$value[unlist(Map(f=seq.int,firstNA,afterNA))] <- rep.int(replacements,occurences)

结果:

> df
   day value
1    1   250
2    2   250
3    3   500
4    4   500
5    5  1500
6    6  1500
7    7  1250
8    8  1250
9    9  1250
10  10  1250
11  11   500
12  12   500
13  13    NA
14  14    NA
15  15    NA