将时间值转换为数字,同时保持时间特性
Convert time values to numeric while keeping time characteristics
我有一个数据集,其中包含不同事件发生的间隔时间。我想要做的是将数据转换为数字向量,以便更容易操作和 运行 summaries/make 图表等,同时保持其时间特性。这是我的数据片段:
data <- c( "03:31", "12:17", "16:29", "09:52", "04:01", "09:00", "06:29",
"04:17", "04:42")
class(data)
[1] character
显而易见的答案是:
as.numeric(data)
但是我得到这个错误:
Warning message:
NAs introduced by coercion
我想也许把':'去掉,但是它失去了它的时间特征。我的意思是,如果我将值加在一起,比如 347 和 543,它会得到 890 而不是 930。这是我用来去掉冒号的代码,它可以很好地达到目的:
Nocolon <- gsub("[:]", "", Data, perl=TRUE)
"0331" "1217" "1629" "0952" "0401" "0900" "0629" "0417" "0442"
所以本质上,我想要的是我的时间值采用易于操作和分析的形式。我的想法是让它成为一个数字向量,但这是基于我对 R 的最低限度的理解。我的实际代码有数千个时间值,我想创建一个图表,让我可以查看和确定这些值是否遵循统计分布。
提前致谢!
这里有一些方法。全部转换为分钟。例如,第一个组件是 "03:31"
,即 3 * 60 + 31 = 211 分钟。 (1) 到 (5) 不使用任何包。
1) %*% 它通过将 data
读入带有小时和分钟的 2 列数据框来工作。将其转换为矩阵,以便矩阵乘以 c(60, 1)
。最后,用 c
解开它。
c(as.matrix(read.table(text = data, sep = ":")) %*% c(60, 1))
[1] 211 737 989 592 241 540 389 257 282
2) 和 这个变体更短。它创建相同的数据框,但然后简单地将第一列 (V1
) 乘以 60,并将其添加到第二列 (V2
)。
with(read.table(text = data, sep = ":"), 60*V1+V2)
[1] 211 737 989 592 241 540 389 257 282
3) complex 这会将每个分量转换为复数,然后对实部和虚部执行所需的运算:
data_c <- as.complex(sub(":(\d+)", "+\1i", data))
60 * Re(data_c) + Im(data_c)
## [1] 211 737 989 592 241 540 389 257 282
3a) (3) 的这种变体也有效并且避免了正则表达式:
data_c <- as.complex(paste0(chartr(":", "+", data), "i"))
60 * Re(data_c) + Im(data_c)
## [1] 211 737 989 592 241 540 389 257 282
4) eval 这会将每个组件转换为算术表达式,计算出分钟数,然后执行计算。当你可以避免使用 eval
时,并不真正推荐使用它,所以这个不太理想:
sapply(parse(text = sub("(\d+):", "60*\1+", data)), eval)
## [1] 211 737 989 592 241 540 389 257 282
5) POSIXlt 我们可以转换为 "POSIXlt"
class 然后使用 hour
和 min
组件:
with(unclass(as.POSIXlt(data, format = "%H:%M")), 60 * hour + min)
## [1] 211 737 989 592 241 540 389 257 282
6) chron 使用 chron 包我们可以粘贴在秒上,转换为 "times"
class 然后转换为分钟:
library(chron)
24 * 60 * as.numeric(times(paste0(data, ":00")))
## [1] 211 737 989 592 241 540 389 257 282
7) lubridate 使用 lubridate 包,我们可以使用 hm
将其转换为数字,最后除以 60 得到分钟:
as.numeric(hm(data)) / 60
## [1] 211 737 989 592 241 540 389 257 282
使用为此设计的as.difftime
函数:
as.difftime(data, format="%H:%M", units="mins")
#Time differences in mins
#[1] 211 737 989 592 241 540 389 257 282
我有一个数据集,其中包含不同事件发生的间隔时间。我想要做的是将数据转换为数字向量,以便更容易操作和 运行 summaries/make 图表等,同时保持其时间特性。这是我的数据片段:
data <- c( "03:31", "12:17", "16:29", "09:52", "04:01", "09:00", "06:29",
"04:17", "04:42")
class(data)
[1] character
显而易见的答案是:
as.numeric(data)
但是我得到这个错误:
Warning message:
NAs introduced by coercion
我想也许把':'去掉,但是它失去了它的时间特征。我的意思是,如果我将值加在一起,比如 347 和 543,它会得到 890 而不是 930。这是我用来去掉冒号的代码,它可以很好地达到目的:
Nocolon <- gsub("[:]", "", Data, perl=TRUE)
"0331" "1217" "1629" "0952" "0401" "0900" "0629" "0417" "0442"
所以本质上,我想要的是我的时间值采用易于操作和分析的形式。我的想法是让它成为一个数字向量,但这是基于我对 R 的最低限度的理解。我的实际代码有数千个时间值,我想创建一个图表,让我可以查看和确定这些值是否遵循统计分布。
提前致谢!
这里有一些方法。全部转换为分钟。例如,第一个组件是 "03:31"
,即 3 * 60 + 31 = 211 分钟。 (1) 到 (5) 不使用任何包。
1) %*% 它通过将 data
读入带有小时和分钟的 2 列数据框来工作。将其转换为矩阵,以便矩阵乘以 c(60, 1)
。最后,用 c
解开它。
c(as.matrix(read.table(text = data, sep = ":")) %*% c(60, 1))
[1] 211 737 989 592 241 540 389 257 282
2) 和 这个变体更短。它创建相同的数据框,但然后简单地将第一列 (V1
) 乘以 60,并将其添加到第二列 (V2
)。
with(read.table(text = data, sep = ":"), 60*V1+V2)
[1] 211 737 989 592 241 540 389 257 282
3) complex 这会将每个分量转换为复数,然后对实部和虚部执行所需的运算:
data_c <- as.complex(sub(":(\d+)", "+\1i", data))
60 * Re(data_c) + Im(data_c)
## [1] 211 737 989 592 241 540 389 257 282
3a) (3) 的这种变体也有效并且避免了正则表达式:
data_c <- as.complex(paste0(chartr(":", "+", data), "i"))
60 * Re(data_c) + Im(data_c)
## [1] 211 737 989 592 241 540 389 257 282
4) eval 这会将每个组件转换为算术表达式,计算出分钟数,然后执行计算。当你可以避免使用 eval
时,并不真正推荐使用它,所以这个不太理想:
sapply(parse(text = sub("(\d+):", "60*\1+", data)), eval)
## [1] 211 737 989 592 241 540 389 257 282
5) POSIXlt 我们可以转换为 "POSIXlt"
class 然后使用 hour
和 min
组件:
with(unclass(as.POSIXlt(data, format = "%H:%M")), 60 * hour + min)
## [1] 211 737 989 592 241 540 389 257 282
6) chron 使用 chron 包我们可以粘贴在秒上,转换为 "times"
class 然后转换为分钟:
library(chron)
24 * 60 * as.numeric(times(paste0(data, ":00")))
## [1] 211 737 989 592 241 540 389 257 282
7) lubridate 使用 lubridate 包,我们可以使用 hm
将其转换为数字,最后除以 60 得到分钟:
as.numeric(hm(data)) / 60
## [1] 211 737 989 592 241 540 389 257 282
使用为此设计的as.difftime
函数:
as.difftime(data, format="%H:%M", units="mins")
#Time differences in mins
#[1] 211 737 989 592 241 540 389 257 282