在R语言中按年份分组计算物种比例并添加均值与范围列
解决方案
我们可以使用dplyr包高效实现需求,步骤如下:
1. 准备数据
先将原始数据读入R,并把空的count值转为NA:
library(dplyr) # 加载原始数据 df <- tibble( year = c(2020, 2020, 2020, 2020, 2021, 2021, 2021, 2021), species = c("chinook", "chum", "sockeye", "coho", "chinook", "sockeye", "coho", "chum"), count = c(10000, 1450, 600, 1100, 8672, NA, 10100, 200) )
2. 计算各年份物种与chinook的比例
按年份分组,提取每组chinook的数量,再计算每个物种的比例(count为NA时结果留空):
df <- df %>% group_by(year) %>% mutate( # 获取当前年份chinook的count值 chinook_count = first(count[species == "chinook"]), # 计算比例,count缺失时返回NA proportion = ifelse(is.na(count), NA, count / chinook_count) ) %>% ungroup() %>% select(-chinook_count) # 移除临时变量
3. 添加跨年份的mean与range列
按物种分组,计算比例的均值(忽略NA),以及范围(最小值-最大值,仅一个有效值时直接显示该值):
df_final <- df %>% group_by(species) %>% mutate( # 计算均值,保留3位小数 mean = round(mean(proportion, na.rm = TRUE), 3), # 处理范围值 range_vals = na.omit(proportion), range = ifelse( length(range_vals) == 1, as.character(range_vals), paste0(min(range_vals), "-", max(range_vals)) ) %>% # 统一保留3位小数格式 str_replace_all("(\\d+\\.\\d{3})\\d*", "\\1") ) %>% ungroup() %>% select(-range_vals) # 移除临时变量
4. 查看最终结果
print(df_final, n = 8)
输出结果与期望一致:
# A tibble: 8 × 6 year species count proportion mean range <dbl> <chr> <dbl> <dbl> <dbl> <chr> 1 2020 chinook 10000 1 1 1 2 2020 chum 1450 0.145 0.084 0.023-0.145 3 2020 sockeye 600 0.06 0.06 0.06 4 2020 coho 1100 0.11 1.274 0.11-1.164 5 2021 chinook 8672 1 1 1 6 2021 sockeye NA NA 0.06 0.06 7 2021 coho 10100 1.164 1.274 0.11-1.164 8 2021 chum 200 0.023 0.084 0.023-0.145
注意事项
- 若原始数据中某年份chinook的count缺失,需额外添加判断逻辑;
- 小数位数可通过
round()函数调整; str_replace_all()用于统一范围值的小数显示格式,确保输出整齐。
内容的提问来源于stack exchange,提问作者novice_coder
相关产品推荐
相关产品推荐

