R语言导入赛艇数据截断问题及MM:SS.MS格式转换需求
赛艇数据导入R后的时间解析与格式化问题
问题场景
从Excel导出的CSV文件中,赛艇时间数据格式为MM:SS.MS(例:01:35.2 表示1分35.2秒),但通过read_csv导入R后,这些数据被错误解析为HH:MM:SS格式,显示为01:35:00(1小时35分),毫秒信息完全丢失,同时时间数值被错误放大。
问题原因
read_csv默认会自动识别时间格式,将带冒号的字符串优先解析为hms/difftime类型,但它误将MM:SS.MS中的前两位当成小时而非分钟,导致解析逻辑完全错误,同时截断了毫秒部分。
解决方案
步骤1:重新导入数据,保留原始字符格式
修改导入代码,指定时间列以字符类型读取,避免自动解析:
# 加载所需包 library(tidyverse) library(here) # 设置文件路径 file <- here("7-stroke, 20-Second, 60-Second & 2,000-meter_Master File Deidentified.csv") # 导入时指定时间列为字符类型,避免自动解析错误 KUWRowPowerDF <- read_csv( file, col_types = cols( `20-Second_Split` = col_character(), `60-Second_Split` = col_character(), `2k_Avg_Split` = col_character(), `2k_Max_Split` = col_character(), `2k_Total_Time_min` = col_character() ) )
步骤2:自定义函数解析与格式化时间
编写函数将MM:SS.MS格式的字符串转换为包含毫秒的数值型时间,再格式化为目标格式:
# 定义解析MM:SS.MS格式的函数 parse_ms_time <- function(time_str) { # 拆分分钟和秒.毫秒部分 parts <- str_split(time_str, ":", simplify = TRUE) mins <- as.numeric(parts[,1]) secs_ms <- as.numeric(parts[,2]) # 计算总秒数(包含毫秒) total_secs <- mins * 60 + secs_ms # 格式化为MM:SS.MS字符串,保留两位毫秒 sprintf("%02d:%05.2f", floor(total_secs / 60), total_secs %% 60) } # 对所有时间列应用格式化函数 KUWRowPowerDF <- KUWRowPowerDF %>% mutate(across(c(`20-Second_Split`, `60-Second_Split`, `2k_Avg_Split`, `2k_Max_Split`, `2k_Total_Time_min`), parse_ms_time))
可选:保留数值型时间用于分析
如果需要后续统计计算,可同时生成数值型的总秒数列:
parse_ms_time_with_value <- function(time_str) { parts <- str_split(time_str, ":", simplify = TRUE) mins <- as.numeric(parts[,1]) secs_ms <- as.numeric(parts[,2]) total_secs <- mins * 60 + secs_ms list( formatted = sprintf("%02d:%05.2f", floor(total_secs/60), total_secs%%60), value = total_secs ) } # 生成格式化显示列和数值计算列 KUWRowPowerDF <- KUWRowPowerDF %>% mutate( across(c(`20-Second_Split`, `60-Second_Split`, `2k_Avg_Split`, `2k_Max_Split`, `2k_Total_Time_min`), ~parse_ms_time_with_value(.)$formatted, .names = "%s_formatted"), across(c(`20-Second_Split`, `60-Second_Split`, `2k_Avg_Split`, `2k_Max_Split`, `2k_Total_Time_min`), ~parse_ms_time_with_value(.)$value, .names = "%s_secs") )
验证结果
处理后,时间列将正确显示为MM:SS.MS格式,例如原始的01:35.2会被解析为95.2秒,格式化后显示为01:35.20(可通过调整sprintf参数修改毫秒位数),数值型列可直接用于后续统计分析。
内容的提问来源于stack exchange,提问作者Joseph M. DeLeo
相关产品推荐
相关产品推荐

