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

如何用dplyr计算含虚拟零值的树种平均材积?

森林调查树种材积均值统计问题解决

问题背景

在计算标准森林调查的树木材积汇总统计量时,需按树种分组输出结果。部分稀有树种仅在少数样地出现,未出现的样地中该树种材积实际为0,但使用dplyr::summarize()默认计算的是该树种出现的样地的均值,而非基于所有调查样地的均值。

原始示例代码

# 加载必要包
library(dplyr) 
library(tidyr)

# 设置随机种子保证可复现
set.seed(63)

# 创建模拟数据
plots <- c(1:25)
species <- c("PSME", "PSME", "PSME", "TSHE", "PSME", "PSME",  "PSME", "THPL", "PIMO3", "ACMA3")
trees <- data.frame(plot_id = rep(plots,5), species = sample(species, 125, replace=TRUE), vol = rnorm(125, 3250, 30)) %>%
  arrange(plot_id)

# 默认方式计算均值(仅统计树种出现的样地,不符合需求)
trees %>% group_by(species) %>% summarize(across(.cols=2, ~mean(.x)))

问题

能否直接通过向dplyr::summarize()传递参数,实现该树种总材积除以调查总样地数来计算均值?

解决方案

临时转换格式方案

通过宽长格式转换补全0值后计算:

# 接上述代码

# 转换为宽格式,按样地聚合各树种材积
trees_sparse <- trees %>% pivot_wider(id_cols = plot_id, names_from=species, values_from = vol, values_fn=sum)

# 将NA替换为0(表示该样地无对应树种材积)
trees_sparse[is.na(trees_sparse)] <- 0

# 转换回长格式
trees_zeros <- trees_sparse %>% pivot_longer(cols = -1, names_to = "Species", values_to = "Volume")

# 计算符合需求的均值
trees_zeros %>%  group_by(Species) %>%  summarize(across(.cols=2, ~mean(.x)))

更简洁的实现方式

方式1:直接计算总材积/总样地数

无需转换格式,直接在分组后计算总材积除以总样地数:

# 获取调查总样地数
total_plots <- n_distinct(trees$plot_id)

# 按树种计算符合需求的均值
trees %>%
  group_by(species) %>%
  summarize(mean_vol = sum(vol) / total_plots)

方式2:用complete补全缺失组合

使用tidyr::complete()补全所有样地-树种的组合,缺失的材积设为0,再计算均值:

trees %>%
  # 补全所有样地与树种的组合,缺失的vol填充为0
  complete(plot_id, species, fill = list(vol = 0)) %>%
  group_by(species) %>%
  summarize(mean_vol = mean(vol))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 14:53:07