我正在搜索R函数的所有帮助,这些函数会将timepan,例如“15分钟”或“1小时”或“6秒”或“1天”转换为日期时间对象,如“00:15:00”或“01:00:00”或“00:00:06”或“1960-01-02 00:00:00”(对此不确定)。我确信这样的函数存在,或者有一种简洁的方法可以避免编程...
更具体地说,我想做这样的事情(使用组合函数名称transform.span.to.time):
library(chron)
times(transform.span.to.time("15 min"))
应该产生与
相同的结果times("00:15:00")
返回类似于“00:15:00”的transform.span.to.time(“15分钟”)之类的函数是否存在,或者是否存在如何做到这一点的技巧?
答案 0 :(得分:6)
我们将假设一个空格分隔数字和单位,并且在“secs”单位之后也没有尾随空格。这将处理混合单位:
test <- "0 hours 15 min 0 secs"
transform.span <- function(test){
testh <- if(!grepl( " hour | hours ", "0 hours 15 min 0 secs")){
# First consequent if no hours
sub("^", "0:", test)} else {
sub(" hour | hours ", ":", test)}
testm <- if(!grepl( " min | minutes ", testh)) {
# first consequent if no minutes
sub(" min | minutes ", "0:", testh)} else{
sub(" min | minutes ", ":", testh) }
test.s <- if(!grepl( " sec| secs| seconds", testm)) {
# first consequent if no seconds
sub(" sec| secs| seconds", "0", testm)} else{
sub(" sec| secs| seconds", "", testm)}
return(times(test.s)) }
### Use
> transform.span(test)
[1] 00:15:00
> test2 <- "21 hours 15 min 38 secs"
> transform.span(test2)
[1] 21:15:38
答案 1 :(得分:4)
第一个解决方案在gsubfn包中使用strapply
并转换为天数,例如1小时是一天的1/24。第二个解决方案转换为R表达式,计算天数然后对其进行评估。
library(gsubfn)
library(chron)
unit2days <- function(d, u)
as.numeric(d) * switch(tolower(u), s = 1, m = 60, h = 3600)/(24 * 3600)
transform.span.to.time <- function(x)
sapply(strapply(x, "(\\d+) *(\\w)", unit2days), sum)
这是第二个解决方案:
library(chron)
transform.span.to.time2 <- function(x) {
x <- paste(x, 0)
x <- sub("h\\w*", "*3600+", x, ignore.case = TRUE)
x <- sub("m\\w*", "*60+", x, ignore.case = TRUE)
x <- sub("s\\w*", "+", x, ignore.case = TRUE)
unname(sapply(x, function(x) eval(parse(text = x)))/(24*3600))
}
试验:
> x <- c("12 hours 3 min 1 sec", "22h", "18 MINUTES 23 SECONDS")
>
> times(transform.span.to.time(x))
[1] 12:03:01 22:00:00 00:18:23
>
> times(transform.span.to.time2(x))
[1] 12:03:01 22:00:00 00:18:23
答案 2 :(得分:3)
基函数?cut.POSIXt
对breaks
的一组指定值有效:
breaks: a vector of cut points _or_ number giving the number of
intervals which ‘x’ is to be cut into *_or_ an interval
specification, one of ‘"sec"’, ‘"min"’, ‘"hour"’, ‘"day"’,
‘"DSTday"’, ‘"week"’, ‘"month"’, ‘"quarter"’ or ‘"year"’,
optionally preceded by an integer and a space, or followed by
‘"s"’. For ‘"Date"’ objects only ‘"day"’, ‘"week"’,
‘"month"’, ‘"quarter"’ and ‘"year"’ are allowed.*
通过输入cut.POSIXt
查看源代码,相关部分以此开头:
else if (is.character(breaks) && length(breaks) == 1L) {
您可以采用本节中的代码来满足您的需求。
答案 3 :(得分:3)
您可以使用difftime
定义时间跨度:
span2time <- function(span, units = c('mins', 'secs', 'hours')) {
span.dt <- as.difftime(span, units = match.arg(units))
format(as.POSIXct("1970-01-01") + span.dt, "%H:%M:%S")
}
例如:
> span2time(15)
[1] "00:15:00"
编辑:修改为生成chron的times
可接受的字符串。
答案 4 :(得分:2)
基于DWin示例,我重新排列了一下,结果如下:
transform.span<-function(timeSpan) {
timeSpanH <- if(!grepl(" hour | hours | hour| hours|hour |hours |hour|hours", timeSpan)) {
# First consequent if no hours
sub("^", "00:", timeSpan)
} else {
sub(" hour | hours | hour| hours|hour |hours |hour|hours", ":", timeSpan)
}
timeSpanM <- if(!grepl( " min | minutes | min| minutes|min |minutes |min|minutes", timeSpanH)) {
# first consequent if no minutes
paste("00:", timeSpanH, sep="")
} else{
sub(" min | minutes | min| minutes|min |minutes |min|minutes", ":", timeSpanH)
}
timeSpanS <- if(!grepl( " sec| secs| seconds|sec|secs|seconds", timeSpanM)) {
# first consequent if no seconds
paste(timeSpanM, "00", sep="")
} else{
sub(" sec| secs| seconds|sec|secs|seconds", "", timeSpanM)
}
return(timeSpanS)
}
### Use
test <- "1 hour 2 min 1 sec"
times(transform.span(test))
test1hour <- "1 hour"
times(transform.span(test1hour))
test15min <- "15 min"
times(transform.span(test15min))
test4sec <- "4 sec"
times(transform.span(test4sec))