2016-11-16 39 views
4

請注意:這是對「數據」來自何處的超簡單解釋,但數據來源與編碼問題無關。如何根據下一個實際值填寫NA值,然後在前面的NAs之間劃分該值?

我有一個數據集,通過每天在管中收集水來創建。 我不能每天都去測量管子(但管子一直在填充),所以水分值記錄中有間隙。 這種僞數據組表示這已經發生在天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,從而每一天的值是500毫升,錯過5天所以值NA,收集在第6天,因此該值是1000ml(從第5天和第6天合併的水),錯過7,8,9,因此數值等於NA,在第10天收集,給出4天2000ml的值),然後每天收集最後兩次)

我想通過下一個「實際」測量的值並將該值除以NA與該值的日期來填補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) 

再次,這僅僅是一個虛擬數據的設置,否則也只是用500「value[is.na(value)] <- 500」取代NA最簡單的方法,但在真實數據集值可以是457.6,779,376等 也試圖做一個循環,但不斷卡住... 任何想法,我怎麼能做到這一點?

幫助是極大的讚賞

回答

4

這裏是一個可能的解決方案:

# 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 
相關問題