Временной ряд озона - PullRequest
       3

Временной ряд озона

0 голосов
/ 05 января 2019

Я работаю с временным рядом непрерывных измерений концентрации озона в атмосферном воздухе в течение 4-месячного периода. Измерения проводятся каждые 5мин14 сек. Примерно 40000 точек данных.

Я начал обрабатывать свои данные в R, но столкнулся с некоторыми проблемами из-за недостатка навыков.

Мой data.frame - Дата в виде символов и концентрация озона в виде числовых значений.

     Date                     O3_ppb
   2018-05-26 17:55:58 UTC    33.95161
   2018-05-26 18:01:12 UTC    35.12605 
   2018-05-26 18:06:28 UTC    36.03172 
   2018-05-26 18:11:42 UTC    36.81590
   2018-05-26 18:16:57 UTC    37.11235 
   2018-05-26 18:22:12 UTC    37.26945

Я хочу проиллюстрировать ежедневную динамику концентрации озона в течение 24 часов на основе данных за один месяц. Это означает, что я хотел бы ежемесячно в среднем каждые 5 минут в течение 24 часов.

Я думал, что мне нужно как-то сортировать данные по группам каждые 5 минут в течение 24 часов. Например, 00:00:00, 00:05:00, 00:10:00… Но так как в измерении есть дрейф, измерение, проведенное в 00:05:00 одного дня, будет проведено в 00:06:20 следующего, и так далее. А поскольку датчик время от времени перезагружается, число наблюдений каждый день тоже немного меняется.

Мой вопрос: Есть ли функция или цикл, который мог бы сортировать мои данные с интервалами в 5 минут, которые также могли бы учитывать дрейф, так что измерения, которые, например, попадают между 00:02:30 - 00:07:30, будут отсортированы в группу под названием 00:05:00 и 00:07:30 - 00:12:30 в группу 00:10:00?

Извините, если это совершенно непонятно, но я новичок в R и в общем программировании. Я действительно надеюсь, что кто-то может мне помочь, поэтому я могу запустить проект

Ответы [ 2 ]

0 голосов
/ 06 января 2019

Вот подход, использующий lubridate, который округляется до ближайших 5 минут, независимо от времени.

# Load data
library(tidyverse); library(lubridate)
df <- read.table(header = T, stringsAsFactors = F,
text = "Date                     O3_ppb
   '2018-05-26 17:55:58 UTC'    33.95161
   '2018-05-26 18:01:12 UTC'    35.12605 
   '2018-05-26 18:06:28 UTC'    36.03172 
   '2018-05-26 18:11:42 UTC'    36.81590
   '2018-05-26 18:16:57 UTC'    37.11235 
   '2018-05-26 18:22:12 UTC'    37.26945") %>%
  mutate(Date = ymd_hms(Date))


df2 <- df %>%
     # By adding 2.5 min = 150 sec and rounding down, we get closest 5 min
     mutate(Date_rnd = floor_date(Date + 150, "5 minutes"),

     # One option is to group by decimal time of day 
     group    = hour(Date_rnd) + minute(Date_rnd)/60,

     # ...or could convert that to a time on a single day, in this case today
     group_as_datetime = floor_date(Sys.time(), "1 day") + group*60*60)

Выход

> df2
#                 Date   O3_ppb            Date_rnd    group   group_as_datetime
#1 2018-05-26 17:55:58 33.95161 2018-05-26 17:55:00 17.91667 2019-01-05 17:55:00
#2 2018-05-26 18:01:12 35.12605 2018-05-26 18:00:00 18.00000 2019-01-05 18:00:00
#3 2018-05-26 18:06:28 36.03172 2018-05-26 18:05:00 18.08333 2019-01-05 18:05:00
#4 2018-05-26 18:11:42 36.81590 2018-05-26 18:10:00 18.16667 2019-01-05 18:10:00
#5 2018-05-26 18:16:57 37.11235 2018-05-26 18:15:00 18.25000 2019-01-05 18:15:00
#6 2018-05-26 18:22:12 37.26945 2018-05-26 18:20:00 18.33333 2019-01-05 18:20:00
0 голосов
/ 05 января 2019

Вот подход data.table, использующий соединение с перекрытием (foverlaps())

library( data.table )

dt <- fread(' Date                     O3_ppb
            "2018-05-26 17:55:58"    33.95161
            "2018-05-26 18:01:12"    35.12605 
            "2018-05-26 18:06:28"    36.03172 
            "2018-05-26 18:11:42"    36.81590
            "2018-05-26 18:16:57"    37.11235 
            "2018-05-26 18:22:12"    37.26945', header = TRUE)

#set to posix
dt[, Date := as.POSIXct( Date, format = "%Y-%m-%d %H:%M:%S", tz = "UTC") ]
#create dummy variables to join on later
dt[, `:=`( Start = Date, Stop = Date ) ]

#create data.table with periods you wish to summarise on later
#notice the +/- 150 (=00:02:30) to set a 5 minute 'bandwidth' around the period.
dt.period <- data.table( period = seq( as.POSIXct( "2018-05-26 00:00:00", format = "%Y-%m-%d %H:%M:%S", tz = "UTC" ),
                                  as.POSIXct( "2018-05-27 00:00:00", format = "%Y-%m-%d %H:%M:%S", tz = "UTC" ),
                                  by = "5 mins"),
                         Start = seq( as.POSIXct( "2018-05-26 00:00:00", format = "%Y-%m-%d %H:%M:%S", tz = "UTC" ) - 150,
                                      as.POSIXct( "2018-05-27 00:00:00", format = "%Y-%m-%d %H:%M:%S", tz = "UTC" ) - 150 ,
                                      by = "5 mins"),
                         Stop = seq( as.POSIXct( "2018-05-26 00:00:00", format = "%Y-%m-%d %H:%M:%S", tz = "UTC" ) + 150,
                                     as.POSIXct( "2018-05-27 00:00:00", format = "%Y-%m-%d %H:%M:%S", tz = "UTC" ) + 150,
                                     by = "5 mins") )

#perform overlap join
#first set keys
setkey(dt.period, Start, Stop)
#then perform join
result <- foverlaps( dt, dt.period, type = "within", nomatch = NA )
#summarise
result[, .( O3_ppb_avg = mean( O3_ppb, na.rm = TRUE ) ), by = .(period) ]

выход

#                 period O3_ppb_avg
# 1: 2018-05-26 17:55:00   33.95161
# 2: 2018-05-26 18:00:00   35.12605
# 3: 2018-05-26 18:05:00   36.03172
# 4: 2018-05-26 18:10:00   36.81590
# 5: 2018-05-26 18:15:00   37.11235
# 6: 2018-05-26 18:20:00   37.26945
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...