R语言实现:按分组统计数据框各唯一元素频率并转换宽表
R实现分组占比宽表转换
实现逻辑
- 按
Group字段分组,统计每组Nb字段的总和 - 组内每条记录的
Nb值除以组内总和,得到对应Family类别的占比 - 将
Family的不同取值展开为独立列,没有对应值的位置填充0 - 若需要补充数据中暂未出现的
Family列(如示例中的E、F),单独新增列赋值为0即可
tidyverse 实现(推荐)
首次使用需先安装依赖包,后续直接加载即可:
# 安装命令(仅首次运行需要) # install.packages(c("dplyr", "tidyr")) library(dplyr) library(tidyr)
转换代码:
# 构造示例数据 df <- data.frame( Group = c(1,2,3,3,3,4,4,5,5), Family = c("A", "B", "A", "B", "C", "D", "A", "B", "D"), Nb = c(15L, 20L, 2L, 1L, 1L, 10L, 5L, 1L, 1L) ) result <- df %>% group_by(Group) %>% # 计算组内占比 mutate(ratio = Nb / sum(Nb)) %>% # 长表转宽表,缺失值填0 pivot_wider( id_cols = Group, names_from = Family, values_from = ratio, values_fill = 0 ) %>% # 补充示例中要求的E、F全0列,不需要可删除 mutate(E = 0, F = 0) %>% # 调整列顺序与示例对齐 select(Group, A, B, C, D, E, F) %>% # 数值保留两位小数匹配示例格式 mutate(across(A:F, ~round(.x, 2)))
运行后输出结果和预期完全一致:
# A tibble: 5 × 7 Group A B C D E F <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 1 1 0 0 0 0 0 2 2 0 1 0 0 0 0 3 3 0.5 0.25 0.25 0 0 0 4 4 0.33 0 0 0.67 0 0 5 5 0 0.5 0 0.5 0 0
基础R实现(无需安装第三方包)
如果不想安装第三方包,可以直接用基础R函数实现:
# 计算每个Group的Nb总和 group_sum <- aggregate(Nb ~ Group, df, sum) df <- merge(df, group_sum, by = "Group", suffixes = c("", "_sum")) # 计算占比 df$ratio <- df$Nb / df$Nb_sum # 生成交叉宽表 result <- as.data.frame.matrix(xtabs(ratio ~ Group + Family, df)) # 补全Group列和缺失的E、F列 result$Group <- as.integer(row.names(result)) result$E <- 0 result$F <- 0 # 调整列顺序、保留两位小数 result <- result[, c("Group", "A", "B", "C", "D", "E", "F")] result[, -1] <- round(result[, -1], 2)
内容的提问来源于stack exchange,提问作者chippycentra
相关产品推荐
相关产品推荐

