0Pricing
R Academy · 课时

计算与聚合中的 NA

控制 mean()、sum() 和其他聚合函数对 NA 的处理方式

计算与聚合中的 NA 是 CoddyKit 上的免费 R Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。

na.rm 参数

大多数 R 汇总函数都接受 na.rm 参数(移除 NA)。设置为 TRUE 时,函数会在计算结果前忽略 NA 值。默认情况下,na.rm = FALSE,因此 NA 会继续传播。

scores <- c(88, NA, 72, 95, NA, 81, 67)
cat('With na.rm=FALSE (default):
')
cat('  mean:', mean(scores), '
')           # NA
cat('  sum: ', sum(scores), '
')            # NA
cat('With na.rm=TRUE:
')
cat('  mean:', mean(scores, na.rm = TRUE), '
')  # 80.6
cat('  sum: ', sum(scores, na.rm = TRUE), '
')   # 403

使用 na.rm 的 mean()

mean(x, na.rm = TRUE) 会计算非缺失值的算术平均值。分母是存在的值的数量,而不是总长度。

temperatures <- c(22.1, NA, 19.8, 25.1, NA, 17.3, 20.0)

cat('Total elements:', length(temperatures), '
')
cat('Present elements:', sum(!is.na(temperatures)), '
')
cat('Mean (na.rm=TRUE):', mean(temperatures, na.rm = TRUE), '
')

# Manual verification
cat('Manual mean:', sum(temperatures, na.rm=TRUE) / sum(!is.na(temperatures)), '
')

使用 na.rm 的 sum()

sum(x, na.rm = TRUE) 只会相加非 NA 值。当逻辑向量可能包含 NA 时统计 TRUE 值,或从不完整数据中计算总数时,这一点非常重要。

sales_daily <- c(1200, NA, 980, 1450, NA, 1100, 890)
cat('Sum (default):', sum(sales_daily), '
')            # NA
cat('Sum (na.rm):  ', sum(sales_daily, na.rm = TRUE), '
')  # 5620

# Count observations meeting a condition (NA-safe)
cat('Days over 1000:', sum(sales_daily > 1000, na.rm = TRUE), '
')

使用 na.rm 的 min() 和 max()

min() 和 max() 也有 na.rm 参数。如果不使用该参数,输入中的单个 NA 就会导致函数返回 NA。使用 na.rm = TRUE 时,函数会返回现有值中的最小值或最大值。

blood_pressure <- c(120, NA, 135, 118, NA, 142, 125, NA, 130)
cat('Max BP (default):', max(blood_pressure), '
')              # NA
cat('Max BP (na.rm):  ', max(blood_pressure, na.rm = TRUE), '
')  # 142
cat('Min BP (na.rm):  ', min(blood_pressure, na.rm = TRUE), '
')  # 118
cat('Range (na.rm):   ', range(blood_pressure, na.rm = TRUE), '
')

使用 na.rm 的 var() 和 sd()

方差(var())和标准差(sd())也支持 na.rm。它们只使用非缺失观测值计算统计量,并自动调整自由度。

exam_scores <- c(78, 85, NA, 92, 68, 75, NA, 88, 91, NA)
n_valid <- sum(!is.na(exam_scores))
cat('Valid observations:', n_valid, '
')
cat('Mean:   ', round(mean(exam_scores, na.rm = TRUE), 2), '
')
cat('SD:     ', round(sd(exam_scores, na.rm = TRUE), 2), '
')
cat('Var:    ', round(var(exam_scores, na.rm = TRUE), 2), '
')

使用 na.rm 的 median() 和 quantile()

与均值相比,median() 和 quantile() 通常对异常值更稳健,但要正确处理缺失值,同样需要使用 na.rm = TRUE。

incomes <- c(45000, NA, 52000, 48000, NA, 210000, 51000, NA, 49000)
cat('Observations:', sum(!is.na(incomes)), '
')
cat('Median income:', median(incomes, na.rm = TRUE), '
')
cat('Mean income:  ', mean(incomes, na.rm = TRUE), '
')  # pulled up by 210000
cat('25th pctile:  ', quantile(incomes, 0.25, na.rm = TRUE), '
')
cat('75th pctile:  ', quantile(incomes, 0.75, na.rm = TRUE), '
')

使用 na.rm 的 prod() 和 cumsum()

prod(x, na.rm = TRUE) 会计算非 NA 值的乘积。cumsum() 等累积函数没有 na.rm 参数——从第一个缺失值开始,NA 会继续传播。

growth_rates <- c(1.05, NA, 1.03, 1.08, NA, 1.02)
cat('Product of rates:', prod(growth_rates, na.rm = TRUE), '
')

# cumsum propagates NAs
values <- c(10, 20, NA, 40, 50)
cat('cumsum (with NA):', cumsum(values), '
')

# Workaround: replace NA first
filled <- replace(values, is.na(values), 0)
cat('cumsum (NA=0):   ', cumsum(filled), '
')

在 apply 函数中使用 na.rm

对矩阵的行或列使用 apply() 时,可以通过 ... 将 na.rm = TRUE 传递给函数。这样可以在忽略 NA 的同时计算汇总值。

m <- matrix(c(88,NA,72, 95,81,NA, 67,75,90), nrow = 3)
cat('Matrix:
'); print(m)

# Row means ignoring NAs
cat('Row means (na.rm=TRUE):', apply(m, 1, mean, na.rm = TRUE), '
')

# Col means ignoring NAs
cat('Col means (na.rm=TRUE):', apply(m, 2, mean, na.rm = TRUE), '
')

使用 na.rm 的 rowSums() / colSums()

rowSums() 和 colSums() 有各自的 na.rm 参数(不会通过 ... 传递)。使用 na.rm = TRUE 时,它们会在求和中将 NA 视为 0。

sales <- matrix(c(100,NA,80, NA,90,70, 110,85,NA), nrow = 3)
cat('Sales matrix:
'); print(sales)

cat('Row sums (na.rm=F):', rowSums(sales), '
')             # NAs propagate
cat('Row sums (na.rm=T):', rowSums(sales, na.rm = TRUE), '
')
cat('Col means (na.rm=T):', colMeans(sales, na.rm = TRUE), '
')

比较:na.rm=FALSE 与 TRUE

了解何时使用 na.rm = TRUE 而不是 FALSE,取决于您的分析意图:FALSE 可确保您意识到数据不完整;TRUE 则根据可用数据计算最佳估计统计量。

# Always check: how much data is missing BEFORE using na.rm=TRUE
collected <- c(78, NA, 85, NA, 91, 74, NA, 88, 82, NA)
pct_missing <- mean(is.na(collected)) * 100
cat('Missing:', round(pct_missing, 1), '% of data
')

if (pct_missing < 20) {
  cat('Acceptable: computing mean with na.rm=TRUE
')
  cat('Mean:', round(mean(collected, na.rm = TRUE), 2), '
')
} else {
  cat('Too much missing data — investigate before computing
')
}

用户函数中的 na.rm

编写您自己的聚合函数时,请加入 na.rm 参数,并将其传递给 R 的基础函数。这样可以使您的函数符合 R 的惯例。

# Custom function with na.rm support
cv <- function(x, na.rm = FALSE) {
  # Coefficient of Variation = SD / mean
  s <- sd(x, na.rm = na.rm)
  m <- mean(x, na.rm = na.rm)
  return(s / m)
}

readings <- c(22.1, NA, 19.8, 25.1, NA, 17.3, 20.0)
cat('CV (na.rm=FALSE):', cv(readings), '
')          # NA
cat('CV (na.rm=TRUE): ', round(cv(readings, na.rm = TRUE), 4), '
')

快速检查

mean(c(10, 20, NA, 40), na.rm = TRUE) 会返回什么?

回顾:计算中的 NA

非常好!本课的要点如下:

  • 大多数聚合函数(mean、sum、min、max、sd 等)都有 na.rm 参数
  • na.rm = FALSE(默认值)表示 NA 会传播——只要有一个值为 NA,结果就是 NA
  • na.rm = TRUE 会忽略 NA,仅根据现有值计算统计量
  • mean(na.rm=TRUE) 的分母是非 NA 值的数量,而不是总长度
  • 使用 na.rm=TRUE 计算统计量前,请务必检查缺失数据所占的比例
  • 请在您自己的聚合函数中加入 na.rm,以遵循 R 的惯例
# Complete summary with na.rm
data_vec <- c(55, NA, 72, 88, NA, 61, 79, NA, 93, 68)
cat('N valid:', sum(!is.na(data_vec)), '
')
cat('Mean:  ', round(mean(data_vec, na.rm=TRUE), 2), '
')
cat('Median:', median(data_vec, na.rm=TRUE), '
')
cat('SD:    ', round(sd(data_vec, na.rm=TRUE), 2), '
')
cat('Min:   ', min(data_vec, na.rm=TRUE), '
')
cat('Max:   ', max(data_vec, na.rm=TRUE), '
')

常见问题解答

「计算与聚合中的 NA」课时是免费的吗?

是的 — 「计算与聚合中的 NA」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。

「计算与聚合中的 NA」这节课中我会学到什么?

控制 mean()、sum() 和其他聚合函数对 NA 的处理方式 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 R Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「计算与聚合中的 NA」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 R Academy 课中编写并运行代码吗?

能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 理解 R 中的 NA
  2. 检测并统计缺失值
  3. 移除与替换 NA 值
  4. 计算与聚合中的 NA
← 返回 R Academy