#r #dataframe #filter #dplyr
#r #фрейм данных #Фильтр #dplyr
Вопрос:
У меня есть данные временных рядов с интервалом в одну минуту (имя фрейма данных — pn.nano). Я хочу преобразовать его в усредненные данные за 5 минут. Но перед усреднением следует убедиться, что каждый 5-минутный интервал имеет не менее 3 значений (т. е. Каждый 5-минутный интервал должен содержать не менее 3 минут данных). Тогда следует выполнять только усреднение, иначе данные должны быть отфильтрованы.
Данные выглядят следующим образом. Имена столбцов (11.5, 15.4 и т.д.) — это загрязнители, изменение которых со временем отслеживается.
nano.pn <- structure(list(datetime = structure(c(1491887640, 1491887700,
1491887760, 1491887820, 1491887880, 1491887940, 1491888000, 1491888060,
1491888120, 1491888180), tzone = "Asia/Calcutta", class = c("POSIXct",
"POSIXt")), `11.5` = c(5938.99, 5530.35, 4825.41, 4439.71, 4357.98,
4467.01, 3956.29, 3880.23, 3469.57, 3356.23), `15.4` = c(9594.94,
9124.55, 8382.42, 8223.1, 8216.26, 8454.1, 8112.84, 7519.49,
7060.94, 7337.3), `20.5` = c(5126.89, 4965.06, 4749.27, 4941.16,
5081.44, 5254.23, 5424.79, 4855.33, 4790.21, 5149.6), `27.4` = c(2936.92,
2882.55, 2704.88, 2856.22, 2868.12, 2909.07, 3106.77, 2887.35,
2802.64, 2853.24), `36.5` = c(1768.23, 1770.75, 1584.26, 1619.82,
1558.73, 1610.95, 1587.24, 1557.97, 1481.79, 1323.94)), row.names = c(NA,
-10L), class = c("tbl_df", "tbl", "data.frame"))
Мой подход заключается в использовании следующего кода:
x <- nano.pn %>% mutate(datetime= floor_date(datetime, unit = "5 mins"))
n <- x %>% group_by(datetime) %>% summarise(countt= n())
n.pn.5min <- x %>% mutate(countt= rep(n$countt,n$countt)) %>% filter(countt>2) %>%
group_by(datetime) %>% summarise_all(mean, na.rm= TRUE)
Хотя это работает нормально, есть ли какой-нибудь лучший подход?
Ответ №1:
Вы имеете в виду что-то вроде приведенного ниже?
nano.pn %>%
mutate(datetime = floor_date(datetime, unit = "5 mins")) %>%
group_by(datetime) %>%
filter(n() >= 3) %>%
summarise_all(mean, na.rm = TRUE)
что дает
# A tibble: 2 x 6
datetime `11.5` `15.4` `20.5` `27.4` `36.5`
<dttm> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2017-04-11 10:45:00 4724. 8480. 4998. 2844. 1629.
2 2017-04-11 10:50:00 3666. 7508. 5055. 2912. 1488.
Комментарии:
1. Я не знал, что n() можно использовать внутри самого filter() . Спасибо.
Ответ №2:
Работает ли это:
> nano.pn %>% mutate(cuttime = cut(datetime, '5 mins')) %>% group_by(cuttime) %>% filter(n() > 3) %>% summarise(across(is.numeric, mean, na.rm = 1))
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 2 x 6
cuttime `11.5` `15.4` `20.5` `27.4` `36.5`
<fct> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2017-04-11 10:44:00 5018. 8708. 4973. 2850. 1660.
2 2017-04-11 10:49:00 3826. 7697. 5095. 2912. 1512.
>
Разница между моим результатом и результатом Томаса заключается в том, что, когда он использовал flood_date, первая строка в фрейме данных, у которой было время «10:44:00.000», изменилась на «10:40:00.000» и не была включена в среднее вычисление, поскольку это было единственное наблюдение в этой группе, а вторая строка во фрейме данных, у которой было время «10:44:00.000», изменилась на «10:40:00.000» и не была включена в среднее вычисление, поскольку это было единственное наблюдение в этой группе, и второев группе было 4 строки. У меня 5 в обеих группах. Поэтому, пожалуйста, используйте какой-либо код, который будет работать для вас.
Комментарии:
1. Спасибо, Картик, что указал на это. Ваш код заставил меня понять, что я должен использовать ceiling_date, а не floor_date. Но да, мне может понадобиться ваш тип кода тоже когда-нибудь в ближайшем будущем. У меня было еще одно сомнение, можете ли вы помочь. Если у меня есть другой набор данных с интервалом в 5 минут, и я хочу получить среднее значение этих данных в соответствии с временной шкалой второго набора данных, возможно ли это?
2. Конечно, вы имеете в виду одинаковые значения загрязняющих веществ, но в разные сроки?
3. Позвольте мне попробовать на примере. Допустим, у меня есть набор данных с независимой переменной «A» с интервалом в 1 минуту, и у меня есть набор данных с зависимой переменной «B» с интервалом в 5 минут. Я хочу получить среднее значение данных «A» за 5 минут, но на той же временной шкале, что и данные «B». Возможно ли это? Если я использую функцию типа left_join() , она выдаст только совпадающие значения обоих наборов данных, но не будет принимать среднее значение.
4. Поскольку они зависят, вы можете объединяться до тех пор, пока совпадает дата-время. т.е., Как указано выше, если данные в «A» сгруппированы в те же интервалы, что и «B», вы можете присоединиться.
5. Я думаю, что будет лучше опубликовать его с примером. Я сделаю это. Спасибо.