Использование xts с временными промежутками, пересекающими календарные даты: Как использовать аргументы period.apply (xts) или POSIXct datetime в этих случаях в R? - PullRequest
2 голосов
/ 17 мая 2019

У меня проблема с применением функции (мин) для определенного повторяющегося периода времени. В основном мои данные выглядят как в этом примере:

library(xts)
start <- as.POSIXct("2018-05-18 00:00")
tseq <- seq(from = start, length.out = 1440, by = "10 mins")
Measurings <- data.frame(
  Time = tseq,
  Temp = sample(10:37,1440, replace = TRUE, set.seed(seed = 10)))
)
Measurings_xts <- xts(Measurings[,-1], Measurings$Time)

с очень признательной помощью ( здесь ) мне удалось выяснить, что должны быть определены функции min и max (в отличие от mean, который работает сразу в period.apply) с помощью вспомогательной функции и затем может быть вычислен для логических аргументов даты-времени (часы, дни, годы ...) с помощью этого решения:

colMin <- function(x, na.rm = FALSE) {
  apply(x, 2, min, na.rm = na.rm)
}

epHours <- endpoints(Measurings_xts, "hours")
Measurings_min <- period.apply(Measurings_xts, epHours, colMin)

Для метеорологического анализа мне нужно рассчитать дополнительные минимумы для менее интуитивного промежутка времени, пересекающего календарный день, который я не могу определить в коде:

Мне нужно вывести минимальную ночную температуру, например, из 2018-05-18 19:00 до 2018-05-19 7:00 утром за каждую ночь в моем наборе данных.

Я пытался переместить временной интервал, манипулируя (перемещая) временной столбец вверх или вниз, чтобы включить ночное время в один календарный день. Поскольку это решение подвержено ошибкам и не работает для моих реальных данных, где некоторые наблюдения отсутствуют. Как использовать функции POSIXct datetime и / или xts для расчета минимумов в этом случае?

Ответы [ 2 ]

1 голос
/ 18 мая 2019

Вы можете решить эту проблему, создав собственные «конечные точки» при использовании period.apply

# Choose the appropriate time ranges
z <- Measurings_xts["T19:00/T07:00"]
# Creating your own "endpoints":
epNights <- which(diff.xts(index(z), units = "mins") > 10) - 1

Вычтите одно значение из каждого индекса, потому что скачки записываются в начале следующего "ночного интервала" в выходных данных which().

Затем добавьте последнюю точку данных в наборе данных к вектору конечных точек, и затем вы можете использовать это в period.apply

epNights <- c(epNights, nrow(z))

Measurings_min <- period.apply(z, epNights, colMin)
Measurings_min
# [,1]
# 2018-05-18 07:00:00   10
# 2018-05-19 07:00:00   10
# 2018-05-20 07:00:00   10
# 2018-05-21 07:00:00   10
# 2018-05-22 07:00:00   10
# 2018-05-23 07:00:00   10
# 2018-05-24 07:00:00   11
# 2018-05-25 07:00:00   10
# 2018-05-26 07:00:00   10
# 2018-05-27 07:00:00   10
# 2018-05-27 23:50:00   12
1 голос
/ 17 мая 2019

вот один подход, который работает путем определения новой группы для каждого ночного интервала

# define the time interval, e.g. from 19:00 to 7:00
from <- 19
to <- 7
hours <- as.numeric(strftime(index(Measurings_xts), format="%H"))
y <- rle(as.numeric(findInterval(hours, c(to,from)) != 1))
y$values[c(TRUE, FALSE)] <-  cumsum(y$values[c(TRUE, FALSE)])
grp <- inverse.rle(y)
# grp is a grouping variable that is 0 for everything outside the 
# defined interval , 1 for the first night, 2 for the second...


s <- split(Measurings_xts, grp); s$`0` <- NULL
# min_value will contain the minimum value for each night interval 
min_value <- sapply(s, min)

# to see the date interval for each value
start <- sapply(s, function(x) as.character(index(x)[1]))
end <- sapply(s, function(x) as.character(index(x)[length(x)]))
data.frame(start, end, min_value)

#                start                 end   min_value
#1           2018-05-18 2018-05-18 06:50:00         10
#2  2018-05-18 19:00:00 2018-05-19 06:50:00         10
#3  2018-05-19 19:00:00 2018-05-20 06:50:00         10
#4  2018-05-20 19:00:00 2018-05-21 06:50:00         10
#5  2018-05-21 19:00:00 2018-05-22 06:50:00         10
#6  2018-05-22 19:00:00 2018-05-23 06:50:00         10
#7  2018-05-23 19:00:00 2018-05-24 06:50:00         11
#8  2018-05-24 19:00:00 2018-05-25 06:50:00         10
#9  2018-05-25 19:00:00 2018-05-26 06:50:00         10
#10 2018-05-26 19:00:00 2018-05-27 06:50:00         10
#11 2018-05-27 19:00:00 2018-05-27 23:50:00         12
...