在R语言中如何按冬季而非年份对月份数据进行分组?
按冬季分组R语言数据框的实现方法
先看你的原始数据构造代码:
year <- c(1949, 1950, 1950, 1950, 1951, 1951, 1951, 1952, 1952, 1952, 1953, 1953, 1953) month <- c(12, 1, 2, 12, 1, 2, 12, 1, 2, 12, 1, 2, 12) df <- data.frame(year, month)
你的需求很明确:把前一年12月 + 当年1-2月归为同一个冬季组,生成winterseason列来标记分组序号。这里有几种简单易理解的实现方式,我给你整理出来:
方法一:生成基准年再转序号(最直观)
核心思路是:把12月的年份"提前"到下一年,作为这个冬季的基准年,相同基准年的行就属于同一个冬季组,最后给不同的基准年分配连续序号。
代码如下:
# 生成冬季基准年:12月用year+1,1-2月用原year df$winter_base_year <- ifelse(df$month == 12, df$year + 1, df$year) # 将基准年转换为连续的分组序号 df$winterseason <- as.integer(factor(df$winter_base_year)) # 不需要中间列的话可以删掉 df <- df[, !names(df) == "winter_base_year"] # 查看最终结果 df
运行后就能得到你想要的输出:
year month winterseason 1 1949 12 1 2 1950 1 1 3 1950 2 1 4 1950 12 2 5 1951 1 2 6 1951 2 2 7 1951 12 3 8 1952 1 3 9 1952 2 3 10 1952 12 4 11 1953 1 4 12 1953 2 4 13 1953 12 5
方法二:一步计算序号(更简洁)
如果不想生成中间列,可以直接通过差值判断来累加序号:
df$winterseason <- cumsum(c(TRUE, diff(ifelse(df$month == 12, df$year + 1, df$year)) != 0))
逻辑是:先生成基准年,然后判断相邻行的基准年是否变化,只要变化就累加一次序号,用cumsum实现连续计数。
方法三:用dplyr包(适合tidyverse用户)
如果你习惯用tidyverse的语法风格,用dplyr写会更流畅:
library(dplyr) df <- df %>% # 生成冬季基准年 mutate(winter_base_year = case_when(month == 12 ~ year + 1, TRUE ~ year)) %>% # 给基准年分配连续序号 mutate(winterseason = dense_rank(winter_base_year)) %>% # 移除中间列 select(-winter_base_year)
dense_rank函数会自动给不同的基准年分配不重复的连续序号,非常省心。
内容的提问来源于stack exchange,提问作者Judith
相关产品推荐
相关产品推荐

