2016-11-16 7 views
4

Обратите внимание: это упрощенное объяснение того, откуда берутся «данные», но откуда эти данные не имеют отношения к вопросу кодирования.Как я могу заполнить значения NA на основе следующего действительного значения, но разделите это значение между предыдущими НС?

У меня есть набор данных, созданный путем сбора воды в трубке каждый день. Я не могу ходить и измерять трубку каждый день (но трубка продолжает заполнять), поэтому в записях воды есть пробелы. Этот набор фиктивных данных показывает, где это произошло в дни 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, так что значение НС, собранный на 6-й день, так что значение 1000 мл (вода с 5-го дня и 6-го дня вместе взятых) пропустили 7,8,9, поэтому значения равны NA, собранные на 10-й день, чтобы дать значение 2000 мл за 4 дня), затем собираются каждый день за последние два)

Я хотел бы заполнить пробелы 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) 

Опять же, это лишь фиктивные данные, установленные в противном случае самый простой способ будет просто заменить NA с 500 с «value[is.na(value)] <- 500», но в наборе реальных данных значения могут быть 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 

 Смежные вопросы

  • Нет связанных вопросов^_^