基于时间序列统计用户区域移动次数及分类移动行为的R语言问题
解决R语言时间序列下的用户区域移动统计问题
先看你给出的原始数据:
user <- c("a", "a", "a", "b", "b", "b", "c", "c", "c", "d", "d", "d", "a", "b", "c") time <- seq.POSIXt(as.POSIXct("12/01/22 21:05", format="%m/%d/%y %H:%M", tz="America/Chicago"), by="5 min", length.out=15) area <- c(1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 2, 2, 1, 1, 1) df<-data.frame(user, time, area)
你之前的代码用n_distinct(area)-1统计移动次数,问题出在这个方法只看用户去过多少个不同区域,完全没考虑时间序列里的连续切换——比如用户b从1→2→1,实际是2次移动,但n_distinct(area)是2,减1后得到1,明显不对。
下面是满足你两个需求的完整解决方案:
步骤1:统计每个用户的区域移动次数
用dplyr的lag()函数获取每个用户上一个时间点的区域,对比当前区域是否变化,再对变化次数求和:
library(dplyr) # 计算移动次数 df <- df %>% group_by(user) %>% mutate( # 标记当前区域与上一个区域是否不同(第一个值默认和自己比,所以是FALSE) is_moved = area != lag(area, default = first(area)), # 统计该用户的总移动次数 times_moved = sum(is_moved) ) %>% ungroup()
运行后:
- 用户a的
times_moved是0(始终在区域1) - 用户b的
times_moved是2(1→2、2→1两次切换) - 用户c、d的
times_moved都是1,完全符合你的要求。
步骤2:识别用户的移动行为类型
通过提取每个用户的去重连续区域序列(比如用户d的1,2,2会被简化为1,2),再判断行为类型:
# 新增行为类型列 df <- df %>% group_by(user) %>% mutate( # 用rle()压缩连续重复的区域,得到去重后的区域序列 compressed_area = list(rle(area)$values), # 根据压缩后的序列判断行为类型 behavior_type = case_when( # 始终在同一个区域 length(compressed_area[[1]]) == 1 ~ ifelse(compressed_area[[1]] == 1, "始终停留在区域1", "始终停留在区域2"), # 从1到2后不再切换 all(compressed_area[[1]] == c(1,2)) ~ "进入区域2后停留", # 从2到1后不再切换 all(compressed_area[[1]] == c(2,1)) ~ "离开区域2后停留在区域1", # 出现多次来回切换(序列长度≥3) length(compressed_area[[1]]) >= 3 ~ "来回切换", # 兜底情况 TRUE ~ "其他类型" ) ) %>% ungroup() %>% select(-compressed_area) # 移除中间辅助列
最终每个用户的行为类型:
- a:始终停留在区域1
- b:来回切换
- c:离开区域2后停留在区域1
- d:进入区域2后停留
最终结果预览
运行完上述代码后,df的前几行大概是这样:
user time area is_moved times_moved behavior_type 1 a 2022-12-01 21:05:00 1 FALSE 0 始终停留在区域1 2 a 2022-12-01 21:10:00 1 FALSE 0 始终停留在区域1 3 a 2022-12-01 21:15:00 1 FALSE 0 始终停留在区域1 4 b 2022-12-01 21:20:00 1 FALSE 2 来回切换 5 b 2022-12-01 21:25:00 2 TRUE 2 来回切换 6 b 2022-12-01 21:30:00 1 TRUE 2 来回切换
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

