在 R 中处理整数时间
Handling integer times in R
我的数据框中的时间记录为整数,如:1005、1405、745、1130、2030 等。如何转换这些整数,以便 R 能够理解并在 strptime 等函数中使用它。预先感谢您的帮助
使用 strptime() 的解决方案
正如 Psidom 在他的评论中指出的那样,您可以将整数转换为字符并使用 strptime()
:
int_times <- c(1005,1405,745,1130,2030)
strptime(as.character(int_times), format="%H%M")
## [1] "2016-04-21 10:05:00 CEST" "2016-04-21 14:05:00 CEST" NA
## [4] "2016-04-21 11:30:00 CEST" "2016-04-21 20:30:00 CEST"
但是,如您所见,一旦号码只有三位数,您 运行 就遇到了麻烦。您可以通过使用 formatC()
将整数格式化为具有四位数字和前导零(如果需要)的字符来解决此问题:
char_times <- formatC(int_times, flag = 0, width = 4)
char_times
[1] "1005" "1405" "0745" "1130" "2030"
现在,转换有效:
strptime(char_times, format="%H%M")
## [1] "2016-04-21 10:05:00 CEST" "2016-04-21 14:05:00 CEST" "2016-04-21 07:45:00 CEST"
## [4] "2016-04-21 11:30:00 CEST" "2016-04-21 20:30:00 CEST"
请注意,strptime()
总是 returns 涉及时间 和 日期的 POSIXct 对象。由于未提供数据,因此使用当天。但您也可以使用 paste()
将时间与任何日期组合:
strptime(paste("2010-03-21", char_times), format="%Y-%m-%d %H%M")
## [1] "2010-03-21 10:05:00 CET" "2010-03-21 14:05:00 CET" "2010-03-21 07:45:00 CET"
## [4] "2010-03-21 11:30:00 CET" "2010-03-21 20:30:00 CET"
解决方案使用 lubridate::hm()
正如 Richard Telford 在他的评论中所建议的那样,如果您不想涉及任何日期,也可以使用 lubridate 的 period
class。此 class 用于时间段,因此您可以表示一个时钟时间,例如 10:23,表示为 10 小时 23 分钟的时间段。但是,仅使用 lubridate 中的 hm()
是行不通的:
library(lubridate)
hm(char_times)
## [1] NA NA NA NA NA
## Warning message:
## In .parse_hms(..., order = "HM", quiet = quiet) :
## Some strings failed to parse
原因是没有分隔符,不清楚这些时间应该怎么转换。 hm()
只需要一个在几分钟之前的表示。但是 "1005"
可能是 100 小时 5 分钟,也可能是 1 小时 5 分钟。所以你需要在小时和分钟之间引入一个分隔符,你可以这样做,例如:
char_times2 <- paste(substr(char_times, 1, 2), substr(char_times, 3, 4))
hm(char_times2)
## [1] "10H 5M 0S" "14H 5M 0S" "7H 45M 0S" "11H 30M 0S" "20H 30M 0S"
请注意,我再次使用了固定宽度的字符串表示法 char_times
,因为小时总是由前两个字符给出。这使得使用 substr()
.
变得容易
我的数据框中的时间记录为整数,如:1005、1405、745、1130、2030 等。如何转换这些整数,以便 R 能够理解并在 strptime 等函数中使用它。预先感谢您的帮助
使用 strptime() 的解决方案
正如 Psidom 在他的评论中指出的那样,您可以将整数转换为字符并使用 strptime()
:
int_times <- c(1005,1405,745,1130,2030)
strptime(as.character(int_times), format="%H%M")
## [1] "2016-04-21 10:05:00 CEST" "2016-04-21 14:05:00 CEST" NA
## [4] "2016-04-21 11:30:00 CEST" "2016-04-21 20:30:00 CEST"
但是,如您所见,一旦号码只有三位数,您 运行 就遇到了麻烦。您可以通过使用 formatC()
将整数格式化为具有四位数字和前导零(如果需要)的字符来解决此问题:
char_times <- formatC(int_times, flag = 0, width = 4)
char_times
[1] "1005" "1405" "0745" "1130" "2030"
现在,转换有效:
strptime(char_times, format="%H%M")
## [1] "2016-04-21 10:05:00 CEST" "2016-04-21 14:05:00 CEST" "2016-04-21 07:45:00 CEST"
## [4] "2016-04-21 11:30:00 CEST" "2016-04-21 20:30:00 CEST"
请注意,strptime()
总是 returns 涉及时间 和 日期的 POSIXct 对象。由于未提供数据,因此使用当天。但您也可以使用 paste()
将时间与任何日期组合:
strptime(paste("2010-03-21", char_times), format="%Y-%m-%d %H%M")
## [1] "2010-03-21 10:05:00 CET" "2010-03-21 14:05:00 CET" "2010-03-21 07:45:00 CET"
## [4] "2010-03-21 11:30:00 CET" "2010-03-21 20:30:00 CET"
解决方案使用 lubridate::hm()
正如 Richard Telford 在他的评论中所建议的那样,如果您不想涉及任何日期,也可以使用 lubridate 的 period
class。此 class 用于时间段,因此您可以表示一个时钟时间,例如 10:23,表示为 10 小时 23 分钟的时间段。但是,仅使用 lubridate 中的 hm()
是行不通的:
library(lubridate)
hm(char_times)
## [1] NA NA NA NA NA
## Warning message:
## In .parse_hms(..., order = "HM", quiet = quiet) :
## Some strings failed to parse
原因是没有分隔符,不清楚这些时间应该怎么转换。 hm()
只需要一个在几分钟之前的表示。但是 "1005"
可能是 100 小时 5 分钟,也可能是 1 小时 5 分钟。所以你需要在小时和分钟之间引入一个分隔符,你可以这样做,例如:
char_times2 <- paste(substr(char_times, 1, 2), substr(char_times, 3, 4))
hm(char_times2)
## [1] "10H 5M 0S" "14H 5M 0S" "7H 45M 0S" "11H 30M 0S" "20H 30M 0S"
请注意,我再次使用了固定宽度的字符串表示法 char_times
,因为小时总是由前两个字符给出。这使得使用 substr()
.