如何计算R数据框各列指定值的占比(计算时忽略NA值)
R实现方案
核心计算逻辑:逐列剔除NA值得到有效样本,分别统计取值1、2、9的出现频次,除以有效样本量得到对应百分比,最终组装为指定结构的数据框。
基础R实现(无依赖)
直接运行以下代码即可得到目标结果,不需要安装额外包:
# 定义需要统计的目标取值 target_val <- c(1, 2, 9) df2 <- as.data.frame( sapply(df, function(col_data) { # 剔除NA值,得到当前列的有效样本 valid_data <- col_data[!is.na(col_data)] valid_n <- length(valid_data) # 计算每个目标值的百分比,保留2位小数 round( vapply(target_val, \(v) sum(valid_data == v) / valid_n * 100, FUN.VALUE = numeric(1)), 2 ) }), row.names = target_val )
运行后输出的df2结构和数值与期望结果一致,仅存在四舍五入带来的微小精度差异:
v1 v2 v3 1 50.00 66.67 16.67 2 50.00 22.22 66.67 9 0.00 11.11 16.67
Tidyverse实现
如果日常使用tidyverse生态处理数据,也可以用以下长宽表转换的逻辑实现:
library(dplyr) library(tidyr) target_val <- c(1, 2, 9) df2 <- df |> # 宽表转长表,统一处理所有列 pivot_longer(everything(), names_to = "col_name", values_to = "val") |> # 剔除NA值 filter(!is.na(val)) |> # 分列分取值统计频次 count(col_name, val) |> # 按列分组计算占比 group_by(col_name) |> mutate(pct = round(n / sum(n) * 100, 2)) |> ungroup() |> # 补全所有目标值,缺失的取值填充占比为0 complete(col_name, val = target_val, fill = list(pct = 0)) |> # 长表转回宽表,匹配原结构 pivot_wider(names_from = col_name, values_from = pct) |> # 把取值列设为行名 column_to_rownames("val")
内容的提问来源于stack exchange,提问作者Fred
相关产品推荐
相关产品推荐

