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

在R语言数据框中按species因子水平添加比例列

按物种分组计算计数比例的R实现

需求说明

现有包含site(站点)、species(物种)、counts(计数)及其他列的数据框,需新增proportions_by_species列,该列值为当前站点的物种计数占该物种所有站点总计数的比例。

修正后的示例数据代码

原示例中cbind会将所有列转为字符型矩阵,建议改用data.frame创建标准数据框:

site <- c(rep("site1",3), rep("site2",4), rep("site3",2))
species <- c("sp1","sp2","sp3","sp1","sp2","sp3","sp4","sp2","sp4")
counts <- c(4,10,22,1,13,23,4,3,1)
data <- data.frame(site, species, counts, stringsAsFactors = FALSE)

初始数据结构:

site species counts
1 site1     sp1      4
2 site1     sp2     10
3 site1     sp3     22
4 site2     sp1      1
5 site2     sp2     13
6 site2     sp3     23
7 site2     sp4      4
8 site3     sp2      3
9 site3     sp4      1

实现方法

方法1:Base R 原生实现

通过聚合计算总计数,再合并回原数据框计算比例:

# 计算每个物种的总计数
species_totals <- aggregate(counts ~ species, data = data, sum)
# 合并总计数到原数据
data_merged <- merge(data, species_totals, by = "species", suffixes = c("", "_total"))
# 计算比例并保留两位小数
data_merged$proportions_by_species <- round(data_merged$counts / data_merged$counts_total, 2)
# 整理列顺序(可选)
data_final <- data_merged[, c("site", "species", "counts", "proportions_by_species")]

方法2:dplyr(Tidyverse)高效实现

利用分组操作简化流程,适合处理大型数据集:

library(dplyr)

data_final <- data %>%
  group_by(species) %>%
  mutate(proportions_by_species = round(counts / sum(counts), 2)) %>%
  ungroup()

最终结果

运行后得到的结果与预期完全匹配:

site species counts proportions_by_species
1 site1     sp1      4                   0.80
2 site1     sp2     10                   0.38
3 site1     sp3     22                   0.49
4 site2     sp1      1                   0.20
5 site2     sp2     13                   0.50
6 site2     sp3     23                   0.51
7 site2     sp4      4                   0.80
8 site3     sp2      3                   0.11
9 site3     sp4      1                   0.20

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 01:37:54