如何在R语言中按用户及场所连续时段分组汇总使用时长?
问题:计算用户连续场所的手机使用总时长
假设记录了随机使用手机的时长数据,需要计算每个用户在连续场所时段的总使用时长(比如Lily有3个连续时段:首次home、随后school、最后home;Sam有2个时段:school、home),无需手动标记period字段,直接从原始数据得到结果。
原始数据的生成代码:
# 生成数据框 library(dplyr) set.seed(1234) my_data <- data.frame( name = c(rep("Lily", 6), rep("Sam", 4)), log_order = c(1:6, 1:4), place = c( rep("home", 2), rep("school", 2), rep("home", 2), rep("school", 2), rep("home", 2) ), use_time = sample(1:10, 10) ) # 查看原始数据 my_data #> name log_order place use_time #> 1 Lily 1 home 10 #> 2 Lily 2 home 6 #> 3 Lily 3 school 5 #> 4 Lily 4 school 4 #> 5 Lily 5 home 1 #> 6 Lily 6 home 8 #> 7 Sam 1 school 2 #> 8 Sam 2 school 7 #> 9 Sam 3 home 9 #> 10 Sam 4 home 3
期望的最终结果:
#> name place tot_use_time #> <chr> <chr> <int> #> 1 Lily home 16 #> 2 Lily school 9 #> 3 Lily home 9 #> 4 Sam school 9 #> 5 Sam home 12
解决方案
通过dplyr的分组和累加逻辑自动生成连续时段的分组标识,无需手动标记period:
my_data %>% group_by(name) %>% # 自动生成连续时段的分组编号 mutate(period = cumsum(place != lag(place, default = first(place)))) %>% # 按用户、时段、场所汇总时长 group_by(name, period, place) %>% summarise(tot_use_time = sum(use_time), .groups = "drop") %>% # 移除period字段 select(-period)
代码逻辑说明
group_by(name):按用户分组,确保每个用户的时段判断独立mutate(period = cumsum(place != lag(place, default = first(place)))):lag(place, default = first(place)):获取当前记录的上一条场所值,第一条记录默认用自身的场所值place != lag(...):判断当前场所是否和上一条不同,不同则返回TRUE(即1),相同则返回FALSE(即0)cumsum():累加上述逻辑值,相同的连续场所会被分到同一个period组
- 后续的
group_by和summarise完成时长汇总,最后移除period字段得到期望结果
内容的提问来源于stack exchange,提问作者Kang
相关产品推荐
相关产品推荐

