You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中按组统计唯一列值并识别非连续年份组?

R实现数据集统计任务方案

首先还原你的数据集:

name = c("john", "john", "john", "alex","alex", "tim", "tim", "tim", "ralph", "ralph")
year = c(2010, 2011, 2012, 2011, 2012, 2010, 2011, 2012, 2014, 2016)
my_data = data.frame(name, year)

任务1:按年份集合分组统计数量

实现思路

先按name聚合对应年份,对每个name的年份排序后拼接成统一格式的字符串(解决年份顺序不同的分组识别问题),最后统计每个字符串的出现次数。

dplyr 实现代码

library(dplyr)

my_data %>%
  group_by(name) %>%
  summarise(year_set = paste(sort(year), collapse = ", ")) %>%
  ungroup() %>%
  count(year_set, name = "count") %>%
  rename(year = year_set)

基础R 实现代码

# 按name聚合并生成排序后的年份字符串
agg <- aggregate(year ~ name, my_data, function(x) paste(sort(x), collapse = ", "))
# 统计每个年份集合的数量
result1 <- as.data.frame(table(agg$year))
colnames(result1) <- c("year", "count")
print(result1)

运行后得到目标输出:

year count
1 2010, 2011, 2012     2
2       2011, 2012     1
3       2014, 2016     1

任务2:统计包含非连续年份的组的数量

实现思路

在任务1基础上,增加对每个name年份序列的连续性判断:计算排序后年份的差值,若存在差值不等于1的情况,说明该组有非连续年份。筛选出这类组后,再统计对应年份集合的数量。

dplyr 实现代码

library(dplyr)

my_data %>%
  group_by(name) %>%
  summarise(
    year_set = paste(sort(year), collapse = ", "),
    has_gap = any(diff(sort(year)) != 1)
  ) %>%
  ungroup() %>%
  filter(has_gap) %>%
  count(year_set, name = "count") %>%
  rename(year = year_set)

基础R 实现代码

# 按name聚合,生成年份字符串并判断是否有非连续
agg <- aggregate(year ~ name, my_data, function(x) {
  sorted_x <- sort(x)
  list(
    year_set = paste(sorted_x, collapse = ", "),
    has_gap = any(diff(sorted_x) != 1)
  )
})
# 转换为数据框并筛选
agg_df <- do.call(rbind, agg$year)
agg_df <- cbind(agg$name, agg_df)
colnames(agg_df) <- c("name", "year", "has_gap")
# 统计符合条件的组数量
result2 <- as.data.frame(table(subset(agg_df, has_gap)$year))
colnames(result2) <- c("year", "count")
print(result2)

运行后得到目标输出:

year count
1 2014, 2016     1

关于确保(2011, 2012)与(2012, 2011)视为同一组的解决方法

核心操作是对每个name对应的年份先执行排序,再拼接成字符串。不管原始数据中年份的顺序如何,排序后生成的字符串都是完全一致的,因此会被识别为同一分组。上面所有代码都包含了sort(year)的步骤,可直接解决该问题。


针对旧版R的任务2解决方案

# 按name聚合年份列表
agg <- aggregate(year ~ name, my_data, c)
# 筛选出年份存在非连续的组
agg <- agg$year[sapply(agg$year, function(y) any(diff(y) != 1))]
# 将年份列表拼接成字符串并统计数量(若需兼容年份顺序问题,可改为paste(sort(y), collapse = ", "))
as.data.frame(table(sapply(agg, paste, collapse = ", ")))

解释:这段代码先通过aggregate按name聚合年份为列表,再用sapply检查每个年份列表的差值是否存在不等于1的情况(即存在非连续年份),筛选出这类列表后,拼接成字符串并统计出现次数。如果原始数据中同一name的年份顺序混乱,建议在paste前加上sort(y),确保同一年份集合不会因顺序被误判为不同组。


内容的提问来源于stack exchange,提问作者stats_noob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:35:22