2

我有这样的数据

y<-c("00:00:10", "00:10:10", "2:10:2")

这些数据采用 H:M:S 格式。我希望能够将此数据转换为总秒数。我喜欢将 H 数据乘以 H*60*60 + M*60 + S 来计算总秒数的值。

我正在这样做:

z <- strptime(, "%H") 

获得小时值,不工作。有人能插话吗?

4

3 回答 3

4

我从来没有掌握处理复杂包裹时间的窍门。这是一个代替它的oneliner。

> apply(sweep(sapply(strsplit(y, ":"), as.integer), 1, 60^(2:0), "*"), 2, sum)
[1]   10  610 7802
于 2012-08-14T17:31:16.800 回答
3

你的工作时间可以超过 24 点吗?如果是这样,我认为您必须将它们视为字符串。2同样在您的示例中,第三次的最后一个是什么意思2:10:2?那是两秒还是二十秒?

我使用这两个函数来回转换:

convertSecToHrMinSec <- function(vec) {
  # takes a vector of seconds
  # returns string formatted as HHH:MM:SS
  vec <- as.integer(vec)
  hr  <- floor(vec / 3600)
  min <- floor((vec - hr * 3600) / 60)
  sec <- vec - min * 60 - hr * 3600
  hr  <- sprintf('%02d', hr)
  min <- sprintf('%02d', min)
  sec <- sprintf('%02d', sec)

  return (paste(hr, min, sec, sep=':'))
}

convertHrMinSecToSec <- function(vec) {
  ## convert hrs:mins:seconds to seconds
  require(stringr)
  require(plyr)
  if (length(grep('.+/.+:.+', vec, perl=TRUE)) >= 1) return(vec)
  if (length(grep('.+:.+:.+', vec, perl=TRUE)) >= 1) {
    vec <- laply(str_split(vec, ':'), function(x) as.integer(x[1]) * 3600 + as.integer(x[2]) * 60 + as.integer(x[3]))
  }

  return (vec)
}

根据上面卡尔的评论,使用lubridate

library(lubridate)
hms(y)

[1] 10 seconds                         10 minutes and 10 seconds          2 hours, 10 minutes and 2 seconds 

为了更好的衡量:

> str(hms(y))
Formal class 'Period' [package "lubridate"] with 6 slots
  ..@ .Data : num [1:3] 10 10 2
  ..@ year  : num [1:3] 0 0 0
  ..@ month : num [1:3] 0 0 0
  ..@ day   : num [1:3] 0 0 0
  ..@ hour  : num [1:3] 0 0 2
  ..@ minute: num [1:3] 0 10 10
> 

periodHadley 创建的类型使用lubridate起来非常愉快,但确实需要一点时间来适应。

于 2012-08-14T15:04:20.457 回答
3

我参加聚会有点晚了,但我认为这是一个很好的方法,因为它使用标准时间函数并且非常简单:

as.integer(as.POSIXct(y,format="%H:%M:%S",tz="GMT")) %% (60*60*24)

[1] 10 610 7802

注意:这仅适用于您的数据是时钟时间的情况。

于 2012-08-14T18:03:40.667 回答