使用R语言dplyr计算每组最大时长结果错误,寻求解决方法
分组计算最大耗时的代码修正
问题背景
需求:计算每组的最大耗时。
原始数据
| 类型(Type) | 开始时间(Start_date) | 结束时间(End_date) |
|---|---|---|
| 素食(Vegetarian) | 2022-06-01 00:00:04 | 2022-06-01 00:02:38 |
| 素食(Vegetarian) | 2022-06-01 00:00:56 | 2022-06-01 00:10:45 |
| 非素食(Non Vegetarian) | 2022-06-01 00:01:39 | 2022-06-01 00:35:04 |
| 素食(Vegetarian) | 2022-06-01 00:01:12 | 2022-06-01 00:20:00 |
| 非素食(Non Vegetarian) | 2022-06-01 00:02:38 | 2022-06-01 08:05:23 |
计算时长列代码
data1$len <- round(difftime(data1$end_date, data1$start_date, units='mins'))
含时长列的结果
| 类型(Type) | 开始时间(start_date) | 结束时间(end_date) | 时长(len) |
|---|---|---|---|
| 素食(Vegetarian) | 2022-06-01 00:00:04 | 2022-06-01 00:02:38 | 3 mins |
| 素食(Vegetarian) | 2022-06-01 00:00:56 | 2022-06-01 00:10:45 | 10 mins |
| 非素食(Non Vegetarian) | 2022-06-01 00:01:39 | 2022-06-01 00:35:04 | 33 mins |
| 素食(Vegetarian) | 2022-06-01 00:01:12 | 2022-06-01 00:20:00 | 19 mins |
| 非素食(Non Vegetarian) | 2022-06-01 00:02:38 | 2022-06-01 08:05:23 | 483 mins |
错误的分组求最大值代码
library(dplyr) data1 %>% group_by(Type) %>% summarise(max_len = max(data1$len))
错误结果
| 类型(Type) | 最大时长(max_len) |
|---|---|
| 素食(Vegetarian) | 483 mins |
| 非素食(Non Vegetarian) | 483 mins |
预期结果
| 类型(Type) | 最大时长(max_len) |
|---|---|
| 素食(Vegetarian) | 19 mins |
| 非素食(Non Vegetarian) | 483 mins |
数据结构
data1 <- structure(list(Type = c("Vegetarian", "Vegetarian", "Non Vegetarian", "Vegetarian", "Non Vegetarian"), start_date = c("2022-06-01 00:00:04", "2022-06-01 00:00:56", "2022-06-01 00:01:39", "2022-06-01 00:01:12", "2022-06-01 00:02:38"), end_date = c("2022-06-01 00:02:38", "2022-06-01 00:10:45", "2022-06-01 00:35:04", "2022-06-01 00:20:00", "2022-06-01 08:05:23" )), class = "data.frame", row.names = c(NA, -5L))
错误原因
在dplyr分组后的summarise函数中,使用data1$len会直接引用整个原始数据框的len列,而非当前分组的子集,因此计算出的是全局最大值483 mins,并重复赋值给每个分组。
修正方案
方案一:直接引用列名(推荐)
利用dplyr的语法特性,直接使用列名len,函数会自动识别当前分组的子集:
library(dplyr) data1 %>% mutate(len = round(difftime(end_date, start_date, units='mins'))) %>% group_by(Type) %>% summarise(max_len = max(len))
方案二:用.指代当前分组数据
如果需要明确指代当前分组的数据集,可以用.表示:
library(dplyr) data1 %>% mutate(len = round(difftime(end_date, start_date, units='mins'))) %>% group_by(Type) %>% summarise(max_len = max(.$len))
补充:规范日期格式处理
原始数据中的start_date和end_date为字符型,虽然difftime可以处理,但转换为日期时间类型更规范:
library(dplyr) library(lubridate) data1 %>% mutate( start_date = ymd_hms(start_date), end_date = ymd_hms(end_date), len = round(difftime(end_date, start_date, units='mins')) ) %>% group_by(Type) %>% summarise(max_len = max(len))
修正后结果
| Type | max_len |
|---|---|
| Vegetarian | 19 mins |
| Non Vegetarian | 483 mins |
内容的提问来源于stack exchange,提问作者Rathna
相关产品推荐
相关产品推荐

