Как получить NA, возвращаемый из агрегата R по данным NA?

У меня есть фрейм данных со столбцом даты и времени POSIXct и столбцом со значением. Значение может содержать периоды NA, иногда даже с задержкой в ​​несколько часов (данные вообще отсутствуют, например).

t                   v
2014-01-01 20:00:00 1000
2014-01-01 20:15:00 2300
2014-01-01 20:30:00 1330
2014-01-01 20:45:00 NA
2014-01-01 21:00:00 NA
2014-01-01 22:15:00 NA
2014-01-01 22:30:00 1330
2014-01-01 22:45:00 3333

Легко увидеть, что есть период, когда данные просто не пишутся (с 21:00 до 22:15). Когда я сейчас подаю заявку

aggregate(data, list(t=cut($t, "1hour"), FUN=sum)

он интерпретирует все, что отсутствует, как ноль. При построении графика с помощью ggplot2 и geom_line кривая в этом регионе изменится с 1000 до 10 с.

Я хочу, чтобы aggregate возвращал значения NA для каждого часа, которые не представлены данными (отсутствуют или сами NA), так что значения не сгибаются до 0 и чтобы линейный график показывал разрыв в этот период (отключенные точки данных ).


person Martin    schedule 21.02.2014    source источник
comment
После того, как вы используете метод @Julien Navarre для создания всех временных шагов, вы можете расширить функцию в агрегате, чтобы, если все значения, которые должны быть суммированы, были NA, она возвращала NA: например, агрегат(данные$v, список(timecat=cut(data$t, час)), функция (z) ifelse (все (is.na (z)), NA, сумма (z, na.rm = T)))   -  person user20650    schedule 21.02.2014
comment
Спасибо, user2060, это важная часть, которую я объединил с окончательным ответом ниже.   -  person Martin    schedule 22.02.2014
comment
Спасибо, что написали свой ответ. Вы можете принять свой собственный ответ.   -  person user20650    schedule 22.02.2014


Ответы (2)


Благодаря @JulienNavarre и @user20650, которые внесли свой вклад в решение, я поместил здесь свое окончательное решение, которое дополнительно способно обрабатывать данные в нестандартное время и требует для агрегирования не менее x значений в час.

data$t <- as.POSIXct(strptime(data$t,"%Y-%m-%d %H:%M:%S"))
x <- 4 # data available x times per hour
h <- 1 # aggregate to every h hours
# aggregation puts NA if data has not x valid values per hour
dataagg <- aggregate(data$v, list(t=cut(data$t, paste(h,"hours"))),
                     function(z) ifelse(length(z)<x*h||any(is.na(z)),NA,sum(z,na.rm=T)))
dataagg$t <- as.POSIXct(strptime(dataagg$t, '%Y-%m-%d %H:%M:%S'))
# Now fill up missing datetimes with NA
a <- seq(min(dataagg$t), max(dataagg$t), by=paste(h,"hours"))
t <- a[seq(1, length(a), by=1)]
tdf <- as.data.frame(t)
tdf$t <- as.POSIXct(strptime(tdf$t, '%Y-%m-%d %H:%M:%S'))
dataaggfinal <- merge(dataagg, tdf, by="t", all.y=T)
person Martin    schedule 22.02.2014

Чего вы хотите, неясно, но, возможно, вы ищете правильное соединение, которое вы можете сделать с merge и all.Y = TRUE.

И после того, как вы можете сгруппировать свою сумму, с агрегатом.

> data$t <- as.POSIXct(data$t)
> 
> time.seq <- seq(min(as.POSIXct(data$t)), max(as.POSIXct(data$t)), by = "min")[seq(1, 166, by = 15)]
> 
> merge(data, as.data.frame(time.seq), by.x = "t", by.y = "time.seq", all.y = T)
                     t    v
1  2014-01-01 20:00:00 1000
2  2014-01-01 20:15:00 2300
3  2014-01-01 20:30:00 1330
4  2014-01-01 20:45:00   NA
5  2014-01-01 21:00:00   NA
6  2014-01-01 21:15:00   NA
7  2014-01-01 21:30:00   NA
8  2014-01-01 21:45:00   NA
9  2014-01-01 22:00:00   NA
10 2014-01-01 22:15:00   NA
11 2014-01-01 22:30:00 1330
12 2014-01-01 22:45:00 3333

И аргумент x в aggregate должен быть, в этом случае, переменной, которую вы хотите «суммировать», тогда ее «данные $ v», а не «данные».

person Julien Navarre    schedule 21.02.2014
comment
Вы просто заменяете NA на 0 и не заполняете пропущенное время. -1 если бы я мог. - person Martin; 21.02.2014