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

基于Base R拆分数据框并绘制多面板物种丰度曲线

Base R实现多面板物种丰度曲线(按年份拆分+分页布局)

我来帮你用Base R搞定这个多面板物种丰度曲线的需求!从数据处理到绘图,一步步给你捋清楚:

1. 先回顾你的原始数据

你提供的示例数据生成代码如下,其中rank列是各年份内lepsp对应freq的降序密集排名(丰度相同则排名重复):

set.seed(453) 
year= as.factor(c(rep("1998", 20), rep("1999", 16))) 
lepsp= c(letters[seq(from = 1, to = 20 )], c('a','b','c'),letters[seq(from =8, to = 20 )]) 
freq= c(sample(1:15, 20, replace=T), sample(1:18, 16,replace=T)) 
df<-data.frame(year, lepsp, freq) 
df<- df %>% group_by(year) %>% mutate(rank = dense_rank(-freq))

2. 需求梳理

你的核心需求可以总结为:

  • 按年份拆分数据框
  • 用Base R绘制多面板物种丰度曲线(x轴为rank,y轴为freq)
  • 采用4行2列的布局,每页最多8张图(22年数据分3页展示)
  • 图中添加25%、50%、75%四分位竖线
  • 每个图标注对应年份,且不重复显示x、y轴标签

3. Base R完整解决方案

下面是完全符合需求的代码,我会逐部分解释:

步骤1:按年份拆分数据框

用Base R自带的split()函数就能快速按年份拆分,得到每个年份对应的子数据框列表:

# 按年份拆分数据框
df_list <- split(df, df$year)
# 确认总年份数量(22年的话这里会返回22)
year_count <- length(df_list)

步骤2:设置分页参数

计算需要的总页数,因为每页最多放8张图(4行2列),用ceiling()向上取整确保所有年份都能展示:

# 计算总页数:22年的话会得到3页(8+8+6)
pages <- ceiling(year_count / 8)

步骤3:循环分页绘图

这部分是核心,我们用par()控制布局、轴标签显示,同时添加四分位线和年份标注:

# 循环处理每一页
for(page in 1:pages){
  # 确定当前页要绘制的年份索引范围
  start_idx <- (page-1)*8 + 1
  end_idx <- min(page*8, year_count)
  current_years <- names(df_list)[start_idx:end_idx]
  
  # 设置4行2列的面板布局,同时调整内外边距避免标签重叠
  par(mfrow = c(4,2), 
      mar = c(3,3,2,1), # 内边距:下、左、上、右
      oma = c(2,2,0,0)) # 外边距:用于放置统一的全局轴标签
  
  # 循环绘制当前页的每个年份图
  for(i in seq_along(current_years)){
    current_df <- df_list[[current_years[i]]]
    # 计算rank的四分位数(针对当前年份的rank列)
    rank_quantiles <- quantile(current_df$rank, c(0.25, 0.5, 0.75))
    
    # 绘制丰度曲线:用折线+点的形式,更清晰展示趋势
    plot(current_df$rank, current_df$freq, 
         type = "b", pch = 16, cex = 0.8,
         # 控制轴标签:先隐藏所有子图的轴标签,最后统一加全局标签
         xlab = "",
         ylab = "",
         main = current_years[i], # 把年份作为子图标题,清晰标注
         xaxt = ifelse(i > 6, "s", "n"), # 仅最后两行显示x轴刻度
         yaxt = ifelse(i %% 2 == 1, "s", "n")) # 仅第一列显示y轴刻度
    
    # 添加四分位竖线:蓝色虚线为25%、75%,红色实线为中位数(50%)
    abline(v = rank_quantiles[1], col = "blue", lty = 2)
    abline(v = rank_quantiles[2], col = "red", lty = 1)
    abline(v = rank_quantiles[3], col = "blue", lty = 2)
    
    # 可选:给四分位线添加文字标签(放在x轴下方)
    text(rank_quantiles, par("usr")[3] - 0.5, 
         labels = c("25%", "50%", "75%"), 
         col = c("blue", "red", "blue"), cex = 0.7)
  }
  
  # 在页面外边缘添加统一的全局x、y轴标签
  mtext("Rank", side = 1, outer = TRUE, line = 0.5, cex = 1.1)
  mtext("Frequency", side = 2, outer = TRUE, line = 0.5, cex = 1.1)
  
  # 非最后一页时,等待用户按回车键切换下一页(避免一次性弹出所有窗口)
  if(page < pages){
    cat("Press Enter to view next page...\n")
    readLines(n = 1)
  }
}

关键细节解释

  • 轴标签控制:通过xaxt/yaxt参数确保只有边缘子图显示刻度,全局轴标签用mtext()放在页面外边缘,彻底避免重复冗余。
  • 四分位线:针对每个年份的rank列单独计算分位数,保证竖线是当前年份的真实分位位置,符合需求。
  • 分页逻辑:自动适配年份数量,22年数据会自动分成3页,最后一页展示剩余的6张图,无需手动调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:40:31