String R从半标准字符串中提取时间分量 安装程序
我有一列持续时间作为字符串存储在数据帧中。我想把它们转换成一个合适的时间对象。大多数字符串都可以使用以下方法轻松解析: 问题String R从半标准字符串中提取时间分量 安装程序,string,r,time,posixct,String,R,Time,Posixct,我有一列持续时间作为字符串存储在数据帧中。我想把它们转换成一个合适的时间对象。大多数字符串都可以使用以下方法轻松解析: 问题 处理所有可能的字符串格式的“R方式”是什么?也许单独测试并提取每个元素,然后重新组合 POSIXlt是正确的目标类吗?我需要不受任何特定开始时间限制的持续时间,因此添加虚假的年和月数据(2012-01-)是一件麻烦事 解决方案 @mplourde在测试日期格式中的各种条件的基础上动态创建格式化字符串的想法绝对正确。添加cut(Sys.Date(),breaks='year
2012-01-
)是一件麻烦事cut(Sys.Date(),breaks='years')
作为datediff
的基线也很好,但未能解释as.POSIXct()
中的一个关键问题注:我使用的是R2.11base,这可能在以后的版本中已经修复
as.POSIXct()
的输出会根据是否包含日期组件而发生显著变化:
> x <- "1 d 1 h 14 m 1 s"
> y <- "1 h 14 m 1 s" # Same string, no date component
> format (x) # as specified below
[1] "%j d %H h %M m %S s"
> format (y)
[1] "% H h % M %S s"
> as.POSIXct(x,format=format) # Including the date baselines at year start
[1] "2012-01-01 01:14:01 EST"
> as.POSIXct(y,format=format) # Excluding the date baselines at today start
[1] "2012-06-26 01:14:01 EDT"
difftime
对象是可以添加到POSIXct
或POSIXlt
对象的持续时间对象。也许你想用这个代替POSIXlt
关于从字符串到时间对象的转换,您可以执行以下操作:
data <- data.frame(time.string = c(
"1 d 1 h",
"30 m 10 s",
"1 d 2 h 3 m 4 s",
"2 h 3 m 4 s",
"10 d 20 h 30 m 40 s",
"--"))
f <- function(x) {
x <- as.character(x)
format <- paste(c(if (grepl('d', x)) '%j d',
if (grepl('h', x)) '%H h',
if (grepl('m', x)) '%M m',
if (grepl('s', x)) '%S s'), collapse=' ')
if (nchar(format) > 0) {
if (grepl('%j d', format)) {
# '%j 1' is day 0. We add a day so that x = '1 d' means 24hrs.
difftime(as.POSIXct(x, format=format) + as.difftime(1, units='days'),
cut(Sys.Date(), breaks='years'),
units='hours')
} else {
as.difftime(x, format, units='hours')
}
} else { NA }
}
data$time.span <- sapply(data$time.string, FUN=f)
数据我想你在以下方面会有更好的运气:
发件人:
5.3。持续时间
持续时间的长度与闰年、闰秒和夏令时不变
因为持续时间是以秒为单位的。因此,持续时间具有一致的长度和长度
可以很容易地与其他持续时间进行比较。持续时间是在以下情况下使用的适当对象:
比较基于时间的属性,例如速度、速率和寿命。
lubridate使用基址R中的difftime类表示持续时间。附加扩散时间方法
我们已经创建了一些工具来促进这一点
lubridate使用基址R中的difftime类表示持续时间。附加扩散时间方法
我们已经创建了一些工具来促进这一点
使用帮助函数dyears()、dweeks()、ddays()、dhours()、dminutes()和dseconds()可以轻松创建Duration对象。标题中的d代表持续时间,并将这些对象与第5.4节中讨论的期间对象区分开来。每个对象使用上面给出的估计关系创建以秒为单位的持续时间
也就是说,我还没有找到一个函数来将字符串解析为持续时间
您还可以看看时间解析是多么优雅。我还没有为R找到这样的库。这可能会给出一些指导:这并不能解决您的问题,但您遇到了问题,因为它不是为解析持续时间而设计的;它旨在解析时间戳。(有些持续时间看起来像时间戳,有些则不像。)@DavidJames好的,这是有道理的。您是否同意@mplourde的观点,即最好先格式化,然后使用as.difftime()
进行强制转换?如果以字符串开头,则必须首先根据定义对其进行解析。:)然后,选择要将其转换到的类型才有意义,difftime
也有意义(lubridate也使用它);format@mplourde感谢您的详细回复,我正在努力实施和测试。我仍在摸索paste()
和sapply()
是如何在R中使用的,所以我需要深入了解这是如何工作的。一个可靠的答案。我做了测试,它对我有效。是的,difftime
是处理持续时间的最佳数据类型。我对该解决方案进行了一些调整,主要是添加了一个units参数以保持一致性:as.difftime(x,format=format,units=“hours”
。奇怪的是,它会产生一些负面的difftime
值,这在持续时间内是非法的。我正在调查哪些情况会导致这种行为。我已经更新了解决方案,以正确处理你的儒略日。这些链接很有用,谢谢。目前我仅限于使用base R 2.11。令人沮丧,但我不得不接受一个约束。F幸运的是,我目前没有自然语言的要求。不过,我有兴趣在将来尝试这样的项目,慢性可能是一种有用的方式。有一家公司在这一领域工作;很有兴趣看看当它工作的时候,你可以把它带到哪里。
> x <- "1 d 1 h 14 m 1 s"
> y <- "1 h 14 m 1 s" # Same string, no date component
> format (x) # as specified below
[1] "%j d %H h %M m %S s"
> format (y)
[1] "% H h % M %S s"
> as.POSIXct(x,format=format) # Including the date baselines at year start
[1] "2012-01-01 01:14:01 EST"
> as.POSIXct(y,format=format) # Excluding the date baselines at today start
[1] "2012-06-26 01:14:01 EDT"
parse.time <- function (x) {
x <- as.character (x)
break.unit <- ifelse(grepl("d",x),"years","days") # chooses cut() unit
format <- paste(c(if (grepl("d", x)) "%j d",
if (grepl("h", x)) "%H h",
if (grepl("m", x)) "%M m",
if (grepl("s", x)) "%S s"), collapse=" ")
if (nchar(format) > 0) {
difftime(as.POSIXct(x, format=format),
cut(Sys.Date(), breaks=break.unit),
units="hours")
} else {NA}
}
data <- data.frame(time.string = c(
"1 d 1 h",
"30 m 10 s",
"1 d 2 h 3 m 4 s",
"2 h 3 m 4 s",
"10 d 20 h 30 m 40 s",
"--"))
f <- function(x) {
x <- as.character(x)
format <- paste(c(if (grepl('d', x)) '%j d',
if (grepl('h', x)) '%H h',
if (grepl('m', x)) '%M m',
if (grepl('s', x)) '%S s'), collapse=' ')
if (nchar(format) > 0) {
if (grepl('%j d', format)) {
# '%j 1' is day 0. We add a day so that x = '1 d' means 24hrs.
difftime(as.POSIXct(x, format=format) + as.difftime(1, units='days'),
cut(Sys.Date(), breaks='years'),
units='hours')
} else {
as.difftime(x, format, units='hours')
}
} else { NA }
}
data$time.span <- sapply(data$time.string, FUN=f)