如何用pivot_wider将样方物种DataFrame转为宽格式并计算占比?
样方物种覆盖百分比的宽格式转换
需求背景
你手头的原始数据是一个包含5个样方列的DataFrame,每列记录了10次观测到的物种(A、B、C),需要转换成以quadrat为标识列,A、B、C各自覆盖百分比为单独列的宽格式数据。
实现方法
方法1:用tidyverse工具包(更直观易读)
通过「宽转长→统计占比→长转宽」的流程实现:
# 先加载tidyverse包 library(tidyverse) # 你的原始数据 df <- data.frame( quad_1 = c('A','A','B','B','C','C','C','C','B','B'), quad_2 = c('A','B','C','B','B','A','B','B','B','B'), quad_3 = c('A','B','A','A','A','A','B','C','A','B'), quad_4 = c('B','C','C','C','C','B','C','A','B','A'), quad_5 = c('C','B','B','A','A','B','B','C','A','A') ) # 执行转换 result_df <- df %>% # 把所有列转成两列:样方名(quadrat)和对应物种(species) pivot_longer(everything(), names_to = "quadrat", values_to = "species") %>% # 按样方和物种分组统计占比 group_by(quadrat, species) %>% summarise(percent = n()/10*100, .groups = "drop") %>% # 转成目标宽格式 pivot_wider(names_from = species, values_from = percent) # 查看结果 print(result_df)
方法2:用Base R实现(无需额外安装包)
直接统计每列的物种频率,再整理成目标格式:
# 你的原始数据 df <- data.frame( quad_1 = c('A','A','B','B','C','C','C','C','B','B'), quad_2 = c('A','B','C','B','B','A','B','B','B','B'), quad_3 = c('A','B','A','A','A','A','B','C','A','B'), quad_4 = c('B','C','C','C','C','B','C','A','B','A'), quad_5 = c('C','B','B','A','A','B','B','C','A','A') ) # 定义计算单列物种百分比的函数 get_percent <- function(col) { freq_table <- table(col) as.numeric(freq_table / length(col) * 100) } # 对每列计算百分比,转成矩阵后整理成DataFrame percent_data <- sapply(df, get_percent) result_df <- data.frame( quadrat = colnames(percent_data), t(percent_data) ) # 查看结果 print(result_df)
两种方法得到的结果一致,比如quad_1中A占20%、B占40%、C占40%,完全匹配实际观测次数的占比。
内容的提问来源于stack exchange,提问作者mbroadribb
相关产品推荐
相关产品推荐

