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

如何使用summarize_all()统计数据集中各列的非NA值数量?

问题描述

我想要创建一个表格,统计数据集中每一列的非NA值数量。我正在使用summarize_all()函数,但无法得到正确的非NA值统计结果。

我参考了相关帖子获取思路,但似乎没能帮我得到想要的统计结果:如果传入summarize_all(n_distinct)会得到不同值的数量,而传入summarize_all(list(n=~n()))或summarize_all(list(n="length")),则会得到行数。

我的期望输出:

ID Female  Male Non_Binary
 5      5     4          3

我哪里出错了?

示例代码

# Sample Code
test <- as_tibble(data.frame(`ID` = c("1","2","3","4","5"),
                             `Female` = c("Female","Female","Female","Female","Female"),
                             `Male` = c(NA,"Male","Male","Male","Male"),
                             `Non_Binary`=c("Non-Binary","Non-Binary","Non-Binary",NA,NA)))

## Attempt 1
summary <- test %>%
  summarize_all(list(n=~n()))
# 输出结果
# A tibble: 1 × 4
#   ID_n Female_n Male_n Non_Binary_n
#  <int>    <int>  <int>        <int>
#1     5        5      5            5

## Attempt 2
summary <- test %>%
  summarize_all(list(n="length"))
# 输出结果
# A tibble: 1 × 4
#   ID_n Female_n Male_n Non_Binary_n
#  <int>    <int>  <int>        <int>
#1     5        5      5            5

## Attempt 3
summary <- test %>%
  summarize_all(n_distinct)
# 输出结果
# A tibble: 1 × 4
#     ID Female  Male Non_Binary
#  <int>  <int> <int>      <int>
#1     5      1     2          2

### 期望输出
# ID Female  Male Non_Binary
#  5      5     4          3

解决方案

你之前的尝试没命中需求,核心问题是选的函数不对:

  • n()和length()返回的是列的总行数,不管单元格是不是NA;
  • n_distinct()统计的是列里不同非NA值的个数,不是非NA值的总数量。

要统计每列的非NA值总数,这几种方法都能解决:

方法1:用summarize_all()结合sum(!is.na(.))

直接通过布尔值统计非NA的数量:

summary <- test %>%
  summarize_all(~sum(!is.na(.)))

运行后输出:

# A tibble: 1 × 4
     ID Female  Male Non_Binary
  <int>  <int> <int>      <int>
1     5      5     4          3

原理很简单:!is.na(.)把每个单元格转成TRUE(非NA)或FALSE(NA),sum()会自动把TRUE当成1、FALSE当成0,加起来就是非NA值的总数。

方法2:用naniar包的n_complete()(更直观)

如果你装了naniar包,直接用专门统计非NA值的函数,代码更简洁:

library(naniar)
summary <- test %>%
  summarize_all(n_complete)

输出结果和方法1完全一致。

方法3:用across()替代已退役的summarize_all()

tidyverse现在推荐用across()代替旧的*_all()系列函数(summarize_all()已经被软弃用),写法如下:

summary <- test %>%
  summarize(across(everything(), ~sum(!is.na(.))))

或者结合naniar:

summary <- test %>%
  summarize(across(everything(), n_complete))

这样就能得到你想要的每列非NA值统计结果了。


内容的提问来源于stack exchange,提问作者Mary Rachel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:27:23