R语言:按国家分组统计指定年份前的出现次数并生成新列
给DataFrame添加按国家和年份统计的累计次数
需求说明
现有两个R语言DataFrame:nobel和nobel2,均包含country(国家)和year(年份)列。需要给nobel2新增nobel_nr列,该列值为nobel中对应国家在nobel2该行年份(含)之前的出现次数。
示例数据
nobel <- data.frame("country" = c("Japan", "USA", "Romania", "Russia", "USA", "USA"), "year" = c(2008, 1934, 2014, 1904, 2021, 1977)) nobel2 <- data.frame("country" = c("Japan", "USA", "Romania", "USA", "USA", "Angola"), "year" = c(2008, 2008, 2008, 2020, 2021, 2023))
原代码问题分析
你写的代码存在三个问题:
- 管道符不完整:
%>应该是%>% - 变量名冲突:
filter中未区分nobel和nobel2的列,导致country == country永远为真,统计的是整个nobel的行数 - 统计方式错误:
count()返回的是带n列的DataFrame,直接as.numeric()无法得到正确的次数值
可行实现方法
方法1:逐行处理(适合小数据集)
用rowwise()让mutate逐行遍历nobel2,通过.data指代当前行的列,避免变量冲突,最后用nrow()统计符合条件的行数:
library(dplyr) nobel2 <- nobel2 %>% rowwise() %>% mutate(nobel_nr = nobel %>% filter(country == .data$country, year <= .data$year) %>% nrow()) %>% ungroup()
运行后nobel2的结果:
| country | year | nobel_nr |
|---|---|---|
| Japan | 2008 | 1 |
| USA | 2008 | 2 |
| Romania | 2008 | 0 |
| USA | 2020 | 2 |
| USA | 2021 | 3 |
| Angola | 2023 | 0 |
方法2:非等值连接(适合大数据集)
先预处理nobel生成各国家的累计获奖次数,再通过非等值连接匹配nobel2的行,效率更高:
library(dplyr) # 预处理nobel,计算每个国家按年份排序后的累计获奖数 nobel_cum <- nobel %>% arrange(country, year) %>% group_by(country) %>% mutate(cum_count = row_number()) %>% ungroup() # 非等值连接,匹配同国家且nobel年份<=nobel2年份的记录,取最大累计数 nobel2 <- nobel2 %>% left_join(nobel_cum, by = join_by(country == country, year >= year), multiple = "all") %>% group_by(country, year.x) %>% summarise(nobel_nr = ifelse(is.na(max(cum_count)), 0, max(cum_count)), .groups = "drop") %>% rename(year = year.x)
内容的提问来源于stack exchange,提问作者anpami
相关产品推荐
相关产品推荐

