如何使用Dplyr对POSIXt类型值进行求和运算?
POSIXct类型数据无法求和的原因及解决办法
问题重现
用到的数据集与处理代码:
df <- data.frame( courts = c("Court 1", "Court 1", "Court 2"), time = c("1:00 hrs", "3:00 hrs", "2:00 hrs") ) # 移除" hrs"后缀 df <- df %>% mutate( time_without_hrs = sub(" hrs", "", time) ) # 转换为POSIXct类型 df$time_without_hrs <- as.POSIXct(df$time_without_hrs, format="%H:%M") # 分组求和时出错 summary_df <- df %>% group_by(courts) %>% summarize( sum_value1 = sum(time_without_hrs), )
出现的错误提示:
Error in `summarize()`: ℹ In argument: `sum_value1 = sum(time_without_hrs)`. ℹ In group 1: `courts = "Court 1"`. Caused by error in `Summary.POSIXct()`: ! 'sum' not defined for "POSIXt" objects Run `rlang::last_trace()` to see where the error occurred.
问题原因
POSIXct是日期时间类型,本质是存储从1970年1月1日0点开始的秒数,用来表示某个具体的时间点,而非时间长度。R不支持对这类时间点对象直接求和——你需要的是时长的累加,而非把几个时间点相加,这逻辑本身不成立。
解决办法
正确思路是把字符串格式的时长转换成**时间差(difftime)**或者数值型的小时/分钟数,再进行分组求和:
方法1:转换为数值型时长(推荐)
直接提取小时和分钟,转换成分钟或小时的数值:
library(dplyr) df <- data.frame( courts = c("Court 1", "Court 1", "Court 2"), time = c("1:00 hrs", "3:00 hrs", "2:00 hrs") ) df <- df %>% mutate( # 转换为总分钟数 total_mins = as.numeric(substr(time, 1, 2)) * 60 + as.numeric(substr(time, 4, 5)), # 转换为总小时数 total_hours = as.numeric(substr(time, 1, 2)) + as.numeric(substr(time, 4, 5)) / 60 ) # 分组求和 summary_df <- df %>% group_by(courts) %>% summarize( total_minutes = sum(total_mins), total_hours = sum(total_hours) )
方法2:使用difftime类型存储时长
difftime是R专门用来表示时间长度的类型,支持求和操作:
library(dplyr) df <- data.frame( courts = c("Court 1", "Court 1", "Court 2"), time = c("1:00 hrs", "3:00 hrs", "2:00 hrs") ) df <- df %>% mutate( time_without_hrs = sub(" hrs", "", time), # 将字符串转换为difftime类型 time_duration = as.difftime(time_without_hrs, format = "%H:%M") ) # 分组求和 summary_df <- df %>% group_by(courts) %>% summarize( total_duration = sum(time_duration) )
内容的提问来源于stack exchange,提问作者Henk Straten
相关产品推荐
相关产品推荐

