如何对数据框中HH:MM格式的duracao列求和并修正异常负值?
解决HH:MM格式字符串求和及异常值修正问题
问题说明
我有一个包含1000多行的data.frame,其中一列duracao存储着HH:MM格式的字符串,需要对该列的值求和并返回HH:MM格式的结果。尝试了两种方法都没成功,还发现列里有-1:-20、-1:-00这类异常负值,得把它们修正成1:20、1:00这种正常格式。
示例数据:
df <- data.frame(duracao = c("00:29", "00:26", "00:38")) # 预期求和结果为01:33
之前尝试的两种方法都有问题:
- 第一种直接把字符串转数值,
as.numeric("00:29")会返回NA,根本没法继续计算; - 第二种用
POSIXct处理,这是用来解析日期时间的工具,不是计算时长的,遇到负值或者非标准格式直接报错。
解决方案
步骤1:修正异常负值并统一格式
先用正则表达式去掉所有负号,再把格式补全为两位的HH:MM:
# 移除所有负号 df$duracao <- gsub("-", "", df$duracao) # 统一格式:补前导零,确保是HH:MM(比如把"1:20"转成"01:20") df$duracao <- sapply(df$duracao, function(x) { parts <- strsplit(x, ":")[[1]] sprintf("%02d:%02d", as.integer(parts[1]), as.integer(parts[2])) })
步骤2:转换为秒数求和,再转回HH:MM格式
把每个时长字符串拆成小时和分钟,计算总秒数后求和,最后转换回HH:MM格式:
library(dplyr) df <- df %>% mutate( # 拆分小时和分钟 hours = as.integer(substr(duracao, 1, 2)), minutes = as.integer(substr(duracao, 4, 5)), # 计算单条记录的总秒数 total_sec = hours * 3600 + minutes * 60 ) # 计算所有记录的总秒数 total_sec_sum <- sum(df$total_sec) # 把总秒数转成HH:MM格式 total_hours <- total_sec_sum %/% 3600 total_minutes <- (total_sec_sum %% 3600) %/% 60 total_duracao <- sprintf("%02d:%02d", total_hours, total_minutes)
完整可运行代码
library(dplyr) # 带异常值的示例数据 df <- data.frame(duracao = c("00:29", "-1:-20", "00:38", "-0:-05")) # 修正异常值并统一格式 df$duracao <- gsub("-", "", df$duracao) df$duracao <- sapply(df$duracao, function(x) { parts <- strsplit(x, ":")[[1]] sprintf("%02d:%02d", as.integer(parts[1]), as.integer(parts[2])) }) # 计算总时长 df <- df %>% mutate( hours = as.integer(substr(duracao, 1, 2)), minutes = as.integer(substr(duracao, 4, 5)), total_sec = hours * 3600 + minutes * 60 ) total_sec_sum <- sum(df$total_sec) total_hours <- total_sec_sum %/% 3600 total_minutes <- (total_sec_sum %% 3600) %/% 60 total_duracao <- sprintf("%02d:%02d", total_hours, total_minutes) print(total_duracao) # 输出结果:02:22(对应00:29 + 01:20 + 00:38 + 00:05的总和)
内容的提问来源于stack exchange,提问作者Érika Soares Coelho
相关产品推荐
相关产品推荐

