【问题标题】:How to extract time after a particular time and before another time in R?如何在R中的特定时间之后和另一个时间之前提取时间?
【发布时间】:2023-03-26 19:50:01
【问题描述】:

我的问题之前可能有人问过。我搜索了,但我找不到。感谢您的回答或参考以前的帖子。我有两个数据集。我的数据集(DF1 和 DF2)包括我想要的变量(V1 和 V2)的日期、时间和值。日期和时间列都属于因子类。这是我的 DF1,包括 V1:

#DF1
Date        Time         V1
6/2/2019  0:00:00        0
6/2/2019  0:01:00        24
.
..
6/2/2019  23:59:00       56
6/3/2019  0:00:00        78
6/3/2019  0:01:00        24
.
..
6/3/2019  23:59:00       32
6/4/2019  0:00:00        14
6/4/2019  0:01:00        62
.
..
6/4/2019  23:59:00       103

然后,这是我的数据 (DF2),其中包括变量 2 (V2)。

#DF2
Date        Time         V2    
6/2/2019  0:00:00        2
6/2/2019  0:01:00        33
.
..
6/2/2019  23:59:00       12
6/3/2019  0:00:00        14
6/3/2019  0:01:00        56
.
..
6/3/2019  23:59:00       67
6/4/2019  0:00:00        94
6/4/2019  0:01:00        43
.
..
6/4/2019  23:59:00       156

首先,我必须根据 DateTime 变量(即日期和时间的组合)组合这两个数据集。所以,我使用了以下代码。

# I used the following to change the date class for DF1 and DF2.
DF1$Date <- as.Date(DF1$Date , "%d/%m/%Y")
DF2$Date <- as.Date(DF2$Date , "%d/%m/%Y")

#Then, I merged Date and Time in each dataset in a variable called "Datetime"
DF1$Datetime <- paste(DF1$Date , DF1$Time)
DF2$Datetime <- paste(DF2$Date , DF2$Time)

#Then, I changed the type of Datetime variable as follows:
DF1$Datetime <- as.POSIXct(DF1$Datetime, format = "%Y-%m-%d %H:%M:%S")
DF2$Datetime <- as.POSIXct(DF2$Datetime, format = "%Y-%m-%d %H:%M:%S")

#After that, I merged the datasets DF1 and DF2 by Datetime variable:
My_DF <- merge(DF1, DF2, by = "Datetime")

现在,我需要提取 My_DF 的子集以及“9:00:00”之后和“22:00:00”之前的时间(记录)。例如,输出应包括但不限于我的数据中 7 天的所有 9:01:00 记录。所以,我尝试了以下方法,但它不起作用:

New_DF <- subset(My_DF, My_DF$Time > "09:00:00" & My_DF$Time < "22:00:00")

New_DF(我想要的输出)应该是:

Date        Time         V1         V2    
6/2/2019  9:01:00        ..         ..
6/3/2019  9:01:00        ..         ..
6/4/2019  9:01:00        ..         ..
6/2/2019  9:02:00        ..         ..
6/3/2019  9:02:00        ..         ..
6/4/2019  9:02:00        ..         ..
..
6/2/2019  21:59:00       ..         ..
6/3/2019  21:59:00       ..         ..
6/3/2019  21:59:00       ..         ..

【问题讨论】:

    标签: r


    【解决方案1】:

    这是一种方法。由于未提供数据,因此不得不创建一些数据

    > # create data as factors
    > dates <- as.factor(paste0('6/', 2:8, '/2019'))
    > times <- as.factor(format(as.POSIXct(seq(0, 86400-60, by = 60), 
    +                            origin = '1970-1-1',
    +                            tz = 'UTC'), 
    +                 format = '%H:%M:%S')
    + )
    > 
    > # create data.frame (tibble)
    > tib <- tibble(date = rep(dates, each = 1440),
    +               time = rep(times, times = 7)
    + )
    > 
    > # select data after converting factors to characters
    > # (try to avoid the use of factors except for categorical data)
    > sel <- filter(tib,
    +               as.character(time) >= '10:00:00' &
    +                 as.character(time) <= '22:00:00'
    + )
    > 
    > glimpse(tib)
    Observations: 10,080
    Variables: 2
    $ date <fct> 6/2/2019, 6/2/2019, 6/2/2019, 6/2/2019, 6/2/2019, 6/2/2019, 6/2/2019, 6/2/2019, 6/2/2019, 6...
    $ time <fct> 00:00:00, 00:01:00, 00:02:00, 00:03:00, 00:04:00, 00:05:00, 00:06:00, 00:07:00, 00:08:00, 0...
    > glimpse(sel)
    Observations: 5,047
    Variables: 2
    $ date <fct> 6/2/2019, 6/2/2019, 6/2/2019, 6/2/2019, 6/2/2019, 6/2/2019, 6/2/2019, 6/2/2019, 6/2/2019, 6/2/2019, 6/2/201...
    $ time <fct> 10:00:00, 10:01:00, 10:02:00, 10:03:00, 10:04:00, 10:05:00, 10:06:00, 10:07:00, 10:08:00, 10:09:00, 10:10:0...
    > 
    

    【讨论】:

      【解决方案2】:

      您可以根据一天中的小时对数据进行子集化:

      #merge two datasets
      New_DF <- merge(transform(df1, 
                      datetime = as.POSIXct(paste(Date, Time), format = "%d/%m/%Y %T")), 
                      transform(df2, 
                      datetime = as.POSIXct(paste(Date, Time), format = "%d/%m/%Y %T")), 
                      by = "datetime")
      #Select relevant columns
      New_DF <- New_DF[c("datetime", "V1", "V2")]
      #Extract hour of the day
      New_DF$hour <- as.integer(format(New_DF$datetime, "%H"))
      #Subset the data based on hour
      New_DF[New_DF$hour >= 9 & New_DF$hour < 22, ]
      

      或者使用tidyverselubridate

      library(tidyverse)
      library(lubridate)
      
      inner_join(df1 %>%
                  unite(Datetime, Date, Time, sep = " ") %>%
                  mutate(Datetime = mdy_hms(Datetime)), 
                 df2 %>%
                  unite(Datetime, Date, Time, sep = " ") %>%
                  mutate(Datetime = mdy_hms(Datetime)), by = "Datetime") %>%
       filter(hour(Datetime) >= 9 & hour(Datetime) < 22)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多