Ameerah
Ameerah

Reputation: 65

Subset dataset with time condition in R

I have a dataset like this in example.txt

"09/Jan/2016" "05:00:22" "304" 449
"09/Jan/2016" "07:00:12" "304" 449
"09/Jan/2016" "10:00:02" "200" 10575
"09/Jan/2016" "11:00:03" "304" 449
"09/Jan/2016" "13:00:03" "304" 449
"09/Jan/2016" "20:00:03" "304" 449 
"09/Jan/2016" "23:00:03" "304" 450 
"10/Jan/2016" "00:00:03" "304" 449 
"10/Jan/2016" "03:00:03" "304" 449 
"10/Jan/2016" "04:00:03" "304" 449 

Can I subset my dataset from range six hour before I run my code in R? For example, I open and run my code in January 10th, at 4:15, so I want subset from my dataset, like

"09/Jan/2016" "23:00:03" "304" 450 
"10/Jan/2016" "00:00:03" "304" 449 
"10/Jan/2016" "03:00:03" "304" 449 
"10/Jan/2016" "04:00:03" "304" 449 

what function should I use for my question? and how to use it?

Upvotes: 3

Views: 928

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 388817

Assuming the 4 columns which you have , have names V1, V2, V3 and V4 and the dataframe is df

You can do this in base R by

mergedDateTime <- as.POSIXct(paste(df$V1, df$V2), format = "%d/%b/%Y %H:%M:%S")
df[(Sys.time() - 6*60*60) <  mergedDateTime & Sys.time() > mergedDateTime, ]

For the given example this would work as,

x <- "01/10/2016 04:15:00"
mergedDateTime <- as.POSIXct(paste(df$V1, df$V2), format = "%d/%b/%Y %H:%M:%S")
df[(as.POSIXct(x, format = "%m/%d/%Y %H:%M:%S") - 6*60*60) <  mergedDateTime & 
                as.POSIXct(x, format = "%m/%d/%Y %H:%M:%S") > mergedDateTime, ]


#        V1       V2      V3  V4
#7  09/Jan/2016 23:00:03 304 450
#8  10/Jan/2016 00:00:03 304 449
#9  10/Jan/2016 03:00:03 304 449
#10 10/Jan/2016 04:00:03 304 449

Upvotes: 2

tchakravarty
tchakravarty

Reputation: 10954

The lubridate and chron packages, when used in conjunction, are very powerful and expressive for working with dates and times:

library(readr)
library(chron)
library(lubridate)

# read the data in
df_foo = read_table(file = '"09/Jan/2016" "05:00:22" "304" 449
"09/Jan/2016" "07:00:12" "304" 449
"09/Jan/2016" "10:00:02" "200" 10575
"09/Jan/2016" "11:00:03" "304" 449
"09/Jan/2016" "13:00:03" "304" 449
"09/Jan/2016" "20:00:03" "304" 449 
"09/Jan/2016" "23:00:03" "304" 450 
"10/Jan/2016" "00:00:03" "304" 449 
"10/Jan/2016" "03:00:03" "304" 449 
"10/Jan/2016" "04:00:03" "304" 449', 
                    col_names = c("Date", "Time", "Value1", "Value2"))

# parse dates and times
df_foo = df_foo %>% 
  mutate(
    # parse the dates
    Date = as.Date(gsub('"', "", Date), format = "%d/%b/%Y"),
    # parse the times
    Time = times(format(gsub('"', "", Time), format = "%H:%M:%S")),
    Value1 = as.integer(gsub('"', "", Value1)),
    # datetime
    Datetime = ISOdatetime(
      month = month(Date), 
      day = days(Date), 
      hour = hours(Time),
      sec = seconds(Time),
      min = minutes(Time),
      year = year(Date)
    )
  )

# filter to data within 6 hours of the current time
df_foo %>% 
  filter(
    Datetime > Sys.time() - dhours(6)
  )

Obviously, given the data sample you have included in the question, this returns nothing.

Upvotes: 2

Related Questions