如何根据下一个实际值填写 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
请注意:这是对 '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