【问题标题】:how to get the time difference between two datetime rows that are in 12 hour system如何获取 12 小时制中两个日期时间行之间的时间差
【发布时间】:2020-07-21 19:56:28
【问题描述】:

我正在尝试获取在不同列上具有日期和时间的数据框中的时差。我首先结合日期和时间列,我已经能够得到差异,但由于时间是 12 小时制,我不断得到负值。 我对 R 不是很精通,也不知道哪里出错了。

我正在添加我使用的代码以及我的数据外观示例。

library(readxl)
library(dplyr)
library(openxlsx)
library(tidyverse)
library(lubridate)

sampledata<-"Date       Time    
10/1/2001   4.00
10/1/2001   4.15
10/1/2001   4.30
10/1/2001   4.45
10/1/2001   5.00
10/1/2001   5.15
10/1/2001   5.30
10/1/2001   5.45
10/1/2001   6.00
10/1/2001   6.15
10/1/2001   6.30
10/2/2001   6.45
10/2/2001   7.00
10/2/2001   7.15
10/2/2001   7.30
10/2/2001   7.45
10/2/2001   8.00
10/2/2001   8.15
10/2/2001   8.30
10/2/2001   8.45
10/2/2001   9.00
10/2/2001   9.15
10/2/2001   9.30
10/2/2001   9.45
10/2/2001   10.00
10/2/2001   10.15
10/2/2001   10.30
10/2/2001   10.45
10/2/2001   11.00
10/2/2001   11.15
10/2/2001   11.30
10/2/2001   11.45
10/2/2001   12.00
10/2/2001   12.15
10/2/2001   12.30
10/2/2001   12.45
10/2/2001   1.00
10/2/2001   1.15
10/2/2001   1.30
10/2/2001   1.45
10/2/2001   2.00
10/2/2001   2.15
10/2/2001   2.30
10/2/2001   2.45
10/2/2001   3.00
10/2/2001   3.15
10/2/2001   3.30
10/2/2001   4.00
10/2/2001   4.15
10/2/2001   4.30
10/2/2001   4.45
10/2/2001   5.00
10/2/2001   5.15
10/2/2001   5.30
10/2/2001   5.45
10/2/2001   6.00
10/3/2001   6.15
10/3/2001   6.30
10/3/2001   6.45
10/3/2001   7.00
10/3/2001   7.15
10/3/2001   7.30
10/3/2001   7.45
10/3/2001   8.00
10/3/2001   8.15
10/3/2001   8.30
10/3/2001   8.45
10/3/2001   9.00
10/3/2001   9.15
10/3/2001   9.30
10/3/2001   9.45
10/3/2001   10.00
10/3/2001   10.15
10/3/2001   10.30
10/3/2001   10.45
10/3/2001   11.00
10/3/2001   11.15
10/3/2001   11.30
10/3/2001   11.45
10/3/2001   12.00
10/3/2001   12.15
10/3/2001   12.30
10/3/2001   12.45
10/3/2001   1.00
10/3/2001   1.15
10/3/2001   1.30
10/3/2001   1.45
10/3/2001   2.00
10/3/2001   2.15
10/3/2001   2.30
10/3/2001   2.45
10/3/2001   3.00
10/3/2001   3.15
10/3/2001   3.30
10/3/2001   3.45
10/3/2001   4.00
10/3/2001   4.15
10/3/2001   4.30
10/3/2001   4.45
10/3/2001   5.00
10/3/2001   5.15
10/3/2001   5.30
10/3/2001   5.45
10/3/2001   6.00"

#read data
usedata <- read.table(text=sampledata, header = TRUE)

#Combining Date and Time columns
usedata$datetime<-with(usedata, mdy(usedata$Date) + hm(usedata$Time))

#Converting datetime to date and time variables
usedata$datetime<-as.POSIXct(usedata$datetime,format="%Y-%m-%d%H:%M:%S")

#Calculating time difference between each time interval 
df<-usedata %>%
  group_by(Date)%>%
  mutate(Time_Duration = (difftime(datetime, lag(datetime, default = datetime[1]), unit='secs'))) 
df

df$Time_Duration

当时间从 12 pm 变为 1 pm 时,df$Time_Duration 给出的时间差为负数。我假设这是一个问题,因为我的时间是 12 小时制,但也许是别的。 我尝试使用 strptime 和 format 将 datetime 列转换为 24 小时,然后再找到差异,但我得到了 datetime 列的 NA 值。

我尝试了以下 strptime 代码来转换为 24 小时

x <- strptime(usedata$datetime, format="%Y-%m-%d %I:%M:%S %p")
x

format(x, "%Y-%m-%d %H:%M:%S")

我能得到的任何帮助将不胜感激。谢谢

【问题讨论】:

  • 嗨。您的日期和时间是否都按照您的示例严格按递增顺序排列?
  • 如果您的数据不包括上午/下午(或类似),您如何“知道”每个时间真正代表什么?
  • 是的,这是一个很长的数据集,从 2001 年到 2010 年,日期在增加
  • r2evans,在没有指定上午/下午的情况下输入了时间列,但是对于每个日期,我都知道时间从上午开始,然后以下午结束,在我的 2001 年 10 月 1 日的示例中,时间从凌晨 4 点开始,到 945 点结束

标签: r lubridate


【解决方案1】:

我认为应该这样做。关键是将时间列中的十进制数字转换为具有固定小数位数的字符串,将日期和时间列粘贴在一起,并在strptime 中使用正确的format。如果在特定日期内连续时间之间的差为负数,您知道您可以将其加上 12 小时以及当天的所有后续时间。

library(lubridate)
library(dplyr)

sampledata %>% 
  mutate(Datetime = as.POSIXct(strptime(paste(Date, format(Time, nsmall = 2)), 
                             format = "%m/%d/%Y %H.%M"))) %>%
  group_by(Date) %>%
  mutate(diff_t = cumsum(as.numeric(c(0, as.numeric(diff(Datetime))) < 0))) %>%
  ungroup() %>%
  mutate(Datetime =  as.POSIXct(ifelse(diff_t == 1, Datetime + hours(12), Datetime),
                     origin = "1970-01-01")) %>%
  select(-diff_t) %>%
  as.data.frame()

产生以下结果:

#>          Date  Time            Datetime
#> 1   10/1/2001  4.00 2001-10-01 04:00:00
#> 2   10/1/2001  4.15 2001-10-01 04:15:00
#> 3   10/1/2001  4.30 2001-10-01 04:30:00
#> 4   10/1/2001  4.45 2001-10-01 04:45:00
#> 5   10/1/2001  5.00 2001-10-01 05:00:00
#> 6   10/1/2001  5.15 2001-10-01 05:15:00
#> 7   10/1/2001  5.30 2001-10-01 05:30:00
#> 8   10/1/2001  5.45 2001-10-01 05:45:00
#> 9   10/1/2001  6.00 2001-10-01 06:00:00
#> 10  10/1/2001  6.15 2001-10-01 06:15:00
#> 11  10/1/2001  6.30 2001-10-01 06:30:00
#> 12  10/2/2001  6.45 2001-10-02 06:45:00
#> 13  10/2/2001  7.00 2001-10-02 07:00:00
#> 14  10/2/2001  7.15 2001-10-02 07:15:00
#> 15  10/2/2001  7.30 2001-10-02 07:30:00
#> 16  10/2/2001  7.45 2001-10-02 07:45:00
#> 17  10/2/2001  8.00 2001-10-02 08:00:00
#> 18  10/2/2001  8.15 2001-10-02 08:15:00
#> 19  10/2/2001  8.30 2001-10-02 08:30:00
#> 20  10/2/2001  8.45 2001-10-02 08:45:00
#> 21  10/2/2001  9.00 2001-10-02 09:00:00
#> 22  10/2/2001  9.15 2001-10-02 09:15:00
#> 23  10/2/2001  9.30 2001-10-02 09:30:00
#> 24  10/2/2001  9.45 2001-10-02 09:45:00
#> 25  10/2/2001 10.00 2001-10-02 10:00:00
#> 26  10/2/2001 10.15 2001-10-02 10:15:00
#> 27  10/2/2001 10.30 2001-10-02 10:30:00
#> 28  10/2/2001 10.45 2001-10-02 10:45:00
#> 29  10/2/2001 11.00 2001-10-02 11:00:00
#> 30  10/2/2001 11.15 2001-10-02 11:15:00
#> 31  10/2/2001 11.30 2001-10-02 11:30:00
#> 32  10/2/2001 11.45 2001-10-02 11:45:00
#> 33  10/2/2001 12.00 2001-10-02 12:00:00
#> 34  10/2/2001 12.15 2001-10-02 12:15:00
#> 35  10/2/2001 12.30 2001-10-02 12:30:00
#> 36  10/2/2001 12.45 2001-10-02 12:45:00
#> 37  10/2/2001  1.00 2001-10-02 13:00:00
#> 38  10/2/2001  1.15 2001-10-02 13:15:00
#> 39  10/2/2001  1.30 2001-10-02 13:30:00
#> 40  10/2/2001  1.45 2001-10-02 13:45:00
#> 41  10/2/2001  2.00 2001-10-02 14:00:00
#> 42  10/2/2001  2.15 2001-10-02 14:15:00
#> 43  10/2/2001  2.30 2001-10-02 14:30:00
#> 44  10/2/2001  2.45 2001-10-02 14:45:00
#> 45  10/2/2001  3.00 2001-10-02 15:00:00
#> 46  10/2/2001  3.15 2001-10-02 15:15:00
#> 47  10/2/2001  3.30 2001-10-02 15:30:00
#> 48  10/2/2001  4.00 2001-10-02 16:00:00
#> 49  10/2/2001  4.15 2001-10-02 16:15:00
#> 50  10/2/2001  4.30 2001-10-02 16:30:00
#> 51  10/2/2001  4.45 2001-10-02 16:45:00
#> 52  10/2/2001  5.00 2001-10-02 17:00:00
#> 53  10/2/2001  5.15 2001-10-02 17:15:00
#> 54  10/2/2001  5.30 2001-10-02 17:30:00
#> 55  10/2/2001  5.45 2001-10-02 17:45:00
#> 56  10/2/2001  6.00 2001-10-02 18:00:00
#> 57  10/3/2001  6.15 2001-10-03 06:15:00
#> 58  10/3/2001  6.30 2001-10-03 06:30:00
#> 59  10/3/2001  6.45 2001-10-03 06:45:00
#> 60  10/3/2001  7.00 2001-10-03 07:00:00
#> 61  10/3/2001  7.15 2001-10-03 07:15:00
#> 62  10/3/2001  7.30 2001-10-03 07:30:00
#> 63  10/3/2001  7.45 2001-10-03 07:45:00
#> 64  10/3/2001  8.00 2001-10-03 08:00:00
#> 65  10/3/2001  8.15 2001-10-03 08:15:00
#> 66  10/3/2001  8.30 2001-10-03 08:30:00
#> 67  10/3/2001  8.45 2001-10-03 08:45:00
#> 68  10/3/2001  9.00 2001-10-03 09:00:00
#> 69  10/3/2001  9.15 2001-10-03 09:15:00
#> 70  10/3/2001  9.30 2001-10-03 09:30:00
#> 71  10/3/2001  9.45 2001-10-03 09:45:00
#> 72  10/3/2001 10.00 2001-10-03 10:00:00
#> 73  10/3/2001 10.15 2001-10-03 10:15:00
#> 74  10/3/2001 10.30 2001-10-03 10:30:00
#> 75  10/3/2001 10.45 2001-10-03 10:45:00
#> 76  10/3/2001 11.00 2001-10-03 11:00:00
#> 77  10/3/2001 11.15 2001-10-03 11:15:00
#> 78  10/3/2001 11.30 2001-10-03 11:30:00
#> 79  10/3/2001 11.45 2001-10-03 11:45:00
#> 80  10/3/2001 12.00 2001-10-03 12:00:00
#> 81  10/3/2001 12.15 2001-10-03 12:15:00
#> 82  10/3/2001 12.30 2001-10-03 12:30:00
#> 83  10/3/2001 12.45 2001-10-03 12:45:00
#> 84  10/3/2001  1.00 2001-10-03 13:00:00
#> 85  10/3/2001  1.15 2001-10-03 13:15:00
#> 86  10/3/2001  1.30 2001-10-03 13:30:00
#> 87  10/3/2001  1.45 2001-10-03 13:45:00
#> 88  10/3/2001  2.00 2001-10-03 14:00:00
#> 89  10/3/2001  2.15 2001-10-03 14:15:00
#> 90  10/3/2001  2.30 2001-10-03 14:30:00
#> 91  10/3/2001  2.45 2001-10-03 14:45:00
#> 92  10/3/2001  3.00 2001-10-03 15:00:00
#> 93  10/3/2001  3.15 2001-10-03 15:15:00
#> 94  10/3/2001  3.30 2001-10-03 15:30:00
#> 95  10/3/2001  3.45 2001-10-03 15:45:00
#> 96  10/3/2001  4.00 2001-10-03 16:00:00
#> 97  10/3/2001  4.15 2001-10-03 16:15:00
#> 98  10/3/2001  4.30 2001-10-03 16:30:00
#> 99  10/3/2001  4.45 2001-10-03 16:45:00
#> 100 10/3/2001  5.00 2001-10-03 17:00:00
#> 101 10/3/2001  5.15 2001-10-03 17:15:00
#> 102 10/3/2001  5.30 2001-10-03 17:30:00
#> 103 10/3/2001  5.45 2001-10-03 17:45:00
#> 104 10/3/2001  6.00 2001-10-03 18:00:00

reprex package (v0.3.0) 于 2020 年 7 月 21 日创建

【讨论】:

  • 非常感谢,它成功了。我刚刚添加了 group_by(Date) %>% mutate(Time_Duration = (difftime(Datetime, lag(Datetime, default = Datetime[1]), unit='secs'))) 来获得差异,现在我没有负值。谢谢
猜你喜欢
  • 2013-09-08
  • 2014-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-08
相关资源
最近更新 更多