0

我想在 R 中转换超过 24 小时的小时数。

例如,我有一个包含小时和分钟的数据框,例如 [HH:MM]:

[1] “111:15” “221:15” “111:15” “221:15” “42:05”

我希望它们像这样在几个小时内转换:

“111.25” “221.25” “111.25” “221.25” “42.08333333”

as.POSIXct() 

功能适用于一般用途,但不超过 24 小时。

4

4 回答 4

2

您可以使用拆分字符串strsplit并使用它sapply来转换所有值。

vec <- c("111:15", "221:15", "111:15", "221:15", "42:05")

sapply(strsplit(vec, ":"), function(x) {
  x <- as.numeric(x)
  x[1] + x[2] / 60
})

结果:

[1] 111.25000 221.25000 111.25000 221.25000  42.08333
于 2013-11-05T10:24:21.767 回答
0

我只会用正则表达式解析字符串。在除以 60之前获取位,:然后在之后的位上添加位:

> foo = c("111:15", "221:15", "111:15", "221:15", "42:05")
> foo
[1] "111:15" "221:15" "111:15" "221:15" "42:05" 
> as.numeric(gsub("([^:]+).*", "\\1", foo)) + as.numeric(gsub(".*:([0-9]{2})$", "\\1", foo))/60
[1] 111.25000 221.25000 111.25000 221.25000  42.08333
于 2013-11-05T10:14:30.867 回答
0

另一种可能性是矢量化函数,例如:

FUN <- function(time){
    hours <- sapply(time,FUN=function(x) as.numeric(strsplit(x,split=":")[[1]][1]))
    minutes <- sapply(time,FUN=function(x) as.numeric(strsplit(x,split=":")[[1]][2]))
    result <- hours+(minutes/60)
    return(as.numeric(result))
}

strsplit用来提取小时和分钟的地方,然后在将分钟除以 60 后取总和。

然后,您可以像这样使用该函数:

FUN(c("111:15","221:15","111:15","221:15","42:05"))

[1] 111.25000 221.25000 111.25000 221.25000  42.08333
于 2013-11-05T10:18:40.690 回答
0

strapplyc这是strapplycgsubfn 包中使用的解决方案。它将每个带括号的正则表达式(即小时和分钟)的匹配传递给第三个参数中描述的函数。该函数可以使用通常的 R 函数表示法指定,它还支持使用公式(在此处使用)的简短形式,其中公式的右侧是函数体,左侧表示参数,默认为自由变量 ( m, h) 在右侧。我们假设原始字符向量是ch

library(gsubfn)
strapply(ch, "(\\d+):(\\d+)", ~ as.numeric(h) + as.numeric(m)/60, simplify = TRUE)

数值处理另一种方法是将 : 替换为 . 并将其数字化为我们想要的:

num <- as.numeric(chartr(":", ".", ch))
trunc(num) + 100 * (num %% 1) / 60

sub 这是另一种方法:

h <- as.numeric(sub(":.*", "", ch))
m <- as.numeric(sub(".*:", "", ch))
h + m / 60

上面的每个代码都给出了一个数字结果,但as.character(...)如果需要一个字符结果,我们可以将每个代码包装起来。

读表

as.matrix(read.table(text = ch, sep = ":")) %*% c(1, 1/60)

评估/解析。这个将每一个映射到一个被评估的 R 表达式中。这个很短,但eval经常不赞成使用:

sapply(parse(text = sub(":", "+(1/60)*", ch)), eval)

添加了其他解决方案。

于 2013-11-05T12:46:30.543 回答