简体   繁体   中英

Categorize time series based on time points in separate dataframe in R

I have a time sequence with intervals of 10 minutes that I want to categorize according to tidal stage (low tide, high tide). Ideally ending up with eg :

     date_time    tidal_stage
30/05/2016 10:50  low
30/05/2016 11:00  low
30/05/2016 11:10  mid
30/05/2016 11:20  mid
30/05/2016 11:30  mid
30/05/2016 11:40  mid
30/05/2016 11:50  high
30/05/2016 12:00  high

Time sequence already generated using:

start_time <- as.POSIXct("2016-05-30 10:50:00", tz="CET")
end_time <- as.POSIXct("2016-07-20 08:50:00", tz="CET")
time_seq <- seq(from=start_time, to=end_time, by="10 min")

I have a separate data frame "hw_lw" containing the times of low water and high water for each date in the time series:

     high_water           low_water       date
1 2016-05-30 07:39:00 2016-05-30 04:14:00 2016-05-30
2 2016-05-30 20:01:00 2016-05-30 16:35:00 2016-05-30
3 2016-05-31 08:49:00 2016-05-31 05:17:00 2016-05-31
4 2016-05-31 21:14:00 2016-05-31 17:48:00 2016-05-31
5 2016-06-01 10:04:00 2016-06-01 06:30:00 2016-06-01
6 2016-06-01 23:36:00 2016-06-01 19:09:00 2016-06-01

How can I add the "tidal_stage" column to the time sequence which categorizes each time as "low", "high" or "mid" tide, where "low tide" = 1.5hrs before and after low water; "high tide" = 1.5hrs before and after high water, and "mid tide" = all other points?

I have thought about using subset, but I have only found out how to do this between specific time intervals (eg between 1pm and 2pm), and not when adding or subtracting time to a specific timepoint (eg 1.5 hours after 2pm).

Any help much appreciated! Thank you.

First of all you need to change the format of your hw_dw dataframe as you have two low waters and two high waters per day:

hw_lw2=data.frame(hw_lw[seq(1,nrow(hw_lw),by=2)],hw_lw[seq(2,nrow(hw_lw),by=2),1:2])
names(hw_lw2)=c("high_water1","low_water1","date","high_water2","low_water2")

Add a tidal_stage column to your first dataframe df, and initalize it to "mid", and have a date column in each dataframe.

df$tidal_stage=rep("mid",nrow(df))
df$date=as.Date(df$time_date)
hw_lw2$date=as.Date(hw_lw2$date)

Then you can perform a left join on the two data.frames using the date as the key, and find out the tidal stages:

df2=merge(df,hw_lw2,by="date")
dt=as.difftime(1.5,units="hours")
df2$tidal_stage[(df2$date_time>(df2$low_water1-dt) & df2$date_time<(df2$low_water1+dt)) | (df2$date_time>(df2$low_water2-dt) & df2$date_time<(df2$low_water2+dt))]="low"
df2$tidal_stage[(df2$date_time>(df2$high_water1-dt) & df2$date_time<(df2$high_water1+dt)) | (df2$date_time>(df2$high_water2-dt) & df2$date_time<(df2$high_water2+dt))]="high"

Finally you can remove the unwanted columns:

df2=subset(df2,select=c("date_time","tidal_stage"))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM