我有一个文件,其中包含记录事件时间的列。有时时间格式为mm:ss,有时末尾有零 - mm:ss:00。见下面的例子:
id time
1 20:50
2 76:58:00
3 56:13:00
4 03:44
当我使用read_csv
阅读此数据时,所有较短格式的值(mm:ss)都标记为NA
。当我使用read_csv('data.csv', col_types = cols(time = col_character()))
将这些值设置为字符串读取时,所有值都会更改为更短的格式(因此我在第二行中有76:58
)。如何解析此time
列以使所有数据都采用一种格式(无论是更短还是更长),而是time
类型的变量,而不会丢失这些输入中的数据格式更短?
为什么在解析为时间时,所有8个字符的值都被'NA'替换?
答案 0 :(得分:0)
以下情况如何?
as.ms <- function(x) {
unlist(lapply(sapply(x, function(w)
strsplit(as.character(w), ":")), function(w) {
if (length(w) == 2) {
w[2] <- sprintf("%s.00", w[2])
} else {
w[2] <- sprintf("%4.2f", as.numeric(w[2]) + as.numeric(w[3]) / 1000);
}
w <- paste0(w[1:2], collapse = ":");
}
))
}
lubridate::ms(as.ms(df$time));
#[1] "20M 50S" "76M 58S" "56M 13S" "3M 44S"
说明:如果需要,as.ms
会添加小数秒;然后你可以使用lubridate::hms
来解析时间。
如果您有毫秒,此方法也可以使用。例如,考虑
df2 <- read.table(text =
"id time
1 20:50
2 76:58:00
3 56:13:250
4 03:44", header = T);
然后
lubridate::ms(as.ms(df2$time));
#[1] "20M 50S" "76M 58S" "56M 13.25S" "3M 44S"
df <- read.table(text =
"id time
1 20:50
2 76:58:00
3 56:13:00
4 03:44", header = T);
答案 1 :(得分:0)
要解决第一个问题(短/长格式):假设time
的所有值都是5个字符(MM:SS)或8个字符(MM:SS:00),您可以转换为这样的短格式,假设数据框名为df1
:
library(dplyr)
df1 %>%
mutate(time = substring(time, 1, 5))
id time
1 1 20:50
2 2 76:58
3 3 56:13
4 4 03:44
此格式允许我们使用ms
包中的lubridate
函数。请注意,您的值不是(就像时钟上的时间一样) - 它们是持续时间。所以你可以像这样转换为Period对象:
library(lubridate)
df1 %>%
mutate(time = substring(time, 1, 5),
ts = ms(time))
id time ts
1 1 20:50 20M 50S
2 2 76:58 76M 58S
3 3 56:13 56M 13S
4 4 03:44 3M 44S
lubridate
还有一个duration
功能,需要更多格式化短格式(添加&#34; M&#34;和#34; S&#34;)。