R Academy · 课时

理解 R 中的 NA

了解 NA 的含义、它为何会传播,以及它与 NULL 的区别

第 1 / 4 课13 个步骤

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

R 中的 NA 是什么?

NA 代表不可用(Not Available),表示缺失或未知的值。不同于 NULL(对象不存在)或 NaN(不是数字),NA 是对确实存在但值未知的数据所使用的占位符。

# NA represents a missing value
height_cm <- c(175, NA, 162, 188, NA, 170)
cat('Heights:', height_cm, '
')
cat('Length:', length(height_cm), '
')  # NA counts as an element
cat('Sum:', sum(height_cm), '
')        # NA propagates

NA 与 NULL 的区别

NA 是向量内部的缺失值——该位置存在,但没有已知的值。NULL 则是整个对象不存在——它的长度为 0,不能存储在向量内部。

# NA: element exists, value unknown
vec_with_na <- c(1, NA, 3)
cat('Vector with NA, length:', length(vec_with_na), '
')  # 3

# NULL: nothing there at all
vec_with_null <- c(1, NULL, 3)
cat('Vector with NULL, length:', length(vec_with_null), '
')  # 2!

# NULL gets dropped; NA is kept
cat('vec_with_na:', vec_with_na, '
')
cat('vec_with_null:', vec_with_null, '
')

NA 与 NaN 的区别

NaN(Not a Number)来自数学上未定义的运算,例如 0/0 或 sqrt(-1)。它是一种特殊的数值,而 NA 是通用的缺失值标记,可用于任何类型。

# NaN from undefined operations
cat('0/0 =', 0/0, '
')          # NaN
cat('sqrt(-1) =', sqrt(-1), '
') # NaN (with warning)
cat('Inf - Inf =', Inf - Inf, '
') # NaN

# NaN IS also NA (a special case)
cat('is.nan(NaN):', is.nan(NaN), '
')
cat('is.na(NaN): ', is.na(NaN), '
')  # TRUE!
cat('is.nan(NA): ', is.nan(NA), '
')  # FALSE

NA 与 Inf 的区别

Inf 和 -Inf 分别表示正无穷和负无穷——它们由 1/0 等运算产生。与 NA 不同,Inf 是一个已知的(虽然极端)数值,可以正常参与比较运算。

cat('1/0 =', 1/0, '
')         # Inf
cat('-1/0 =', -1/0, '
')       # -Inf
cat('Inf + 1 =', Inf + 1, '
') # Inf
cat('Inf > 1000:', Inf > 1000, '
')  # TRUE
cat('is.infinite(Inf):', is.infinite(Inf), '
')
cat('is.na(Inf):       ', is.na(Inf), '
')  # FALSE

算术运算中的 NA 传播

NA 在算术运算中具有传染性:任何涉及 NA 的运算都会返回 NA。这是有意设计的——如果计算中的某个值未知,结果也会未知。

x <- NA
cat('NA + 5:  ', x + 5, '
')      # NA
cat('NA * 0:  ', x * 0, '
')      # NA (not 0!)
cat('NA == NA:', x == NA, '
')     # NA (not TRUE!)
cat('NA > 5:  ', x > 5, '
')      # NA
cat('sum(1,NA):', sum(1, NA), '
') # NA

typeof(NA) — 带类型的 NA

默认的 NA 类型为 logical。R 为每种原子类型都提供了带类型的 NA 变体。在处理带类型的向量时,它们非常重要,可以避免意外的类型强制转换。

cat('typeof(NA):            ', typeof(NA), '
')           # logical
cat('typeof(NA_integer_):  ', typeof(NA_integer_), '
')   # integer
cat('typeof(NA_real_):     ', typeof(NA_real_), '
')      # double
cat('typeof(NA_complex_):  ', typeof(NA_complex_), '
')   # complex
cat('typeof(NA_character_):', typeof(NA_character_), '
') # character

NA_integer_ 的实际应用

创建包含缺失值的整数向量时,请使用 NA_integer_,以保持向量类型一致。在某些上下文中,直接使用 NA 会导致隐式强制转换为双精度类型。

# Using plain NA in an integer vector
v1 <- c(1L, 2L, NA, 4L)
cat('typeof with NA:         ', typeof(v1), '
')  # integer (OK here)

# Explicit typed NA is safer in functions
v2 <- c(1L, 2L, NA_integer_, 4L)
cat('typeof with NA_integer_:', typeof(v2), '
')  # integer

# Check they behave the same
cat('Same?', identical(v1, v2), '
')

NA_real_ 和 NA_character_

NA_real_ 用于双精度(数值)向量中的缺失值,NA_character_ 用于缺失字符串。在函数内部构建向量时,类型一致性很重要,因此这两者尤其有用。

# Character vector with missing
names_vec <- c('Alice', 'Bob', NA_character_, 'Dave')
cat('Names:', names_vec, '
')
cat('typeof:', typeof(names_vec), '
')

# Numeric with missing
readings <- c(22.5, NA_real_, 21.3, NA_real_, 24.1)
cat('Readings:', readings, '
')
cat('Non-NA count:', sum(!is.na(readings)), '
')

逻辑运算中的 NA

逻辑运算中的 NA 遵循三值逻辑:TRUE | NA 的结果是 TRUE(因为 TRUE OR 任意值都为 TRUE),但 FALSE | NA 的结果是 NA(不知道 NA 的值,就无法确定结果)。

cat('TRUE  | NA:', TRUE | NA, '
')   # TRUE
cat('FALSE | NA:', FALSE | NA, '
')  # NA
cat('TRUE  & NA:', TRUE & NA, '
')   # NA
cat('FALSE & NA:', FALSE & NA, '
')  # FALSE

# Never use == to test for NA!
cat('NA == NA:', NA == NA, '
')    # NA (not TRUE!)
cat('is.na(NA):', is.na(NA), '
')  # TRUE (correct way)

向量和数据框中的 NA

现实世界的数据中经常会出现缺失值。了解 NA 的行为有助于您正确解读汇总结果、发现数据质量问题,并选择合适的处理策略。

ages <- c(25, NA, 32, NA, 29, 41, NA, 35)
cat('Ages:', ages, '
')
cat('Length:', length(ages), '
')
cat('Missing count:', sum(is.na(ages)), '
')
cat('Present count:', sum(!is.na(ages)), '
')
cat('Mean (fails):', mean(ages), '
')           # NA
cat('Mean (works):', mean(ages, na.rm = TRUE), '
') # 32.4

NA 类型:完整概览

下面汇总了 R 中与 NA 相关的特殊值:

  • NA — 通用缺失值(逻辑类型)
  • NA_integer_、NA_real_、NA_complex_、NA_character_ — 带类型的 NA
  • NaN — 未定义的数值(0/0、sqrt(-1) 的结果)
  • Inf、-Inf — 无穷值(1/0 的结果)
  • NULL — 对象不存在(长度为 0)
# Test functions for special values
x <- c(1, NA, NaN, Inf, -Inf, 0)
cat('Values:         ', x, '
')
cat('is.na():        ', is.na(x), '
')        # TRUE for NA and NaN
cat('is.nan():       ', is.nan(x), '
')       # TRUE only for NaN
cat('is.infinite():  ', is.infinite(x), '
')  # TRUE for Inf and -Inf
cat('is.finite():    ', is.finite(x), '
')    # TRUE only for normal numbers

快速检查

在 R 中,NA == NA 的结果是什么?

回顾:理解 NA

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

  • NA = 缺失值(已知该值存在,但具体值未知)
  • NULL = 对象不存在(会从向量中移除)
  • NaN = 未定义的算术结果(同时也是 NA)
  • Inf / -Inf = 无穷值(不是 NA)
  • NA 在算术运算中具有传染性——对 NA 进行运算会返回 NA
  • 使用带类型的 NA(如 NA_integer_)编写类型安全的代码
  • 始终使用 is.na() 检查 NA,绝不要使用 == NA
# Key tests side by side
special_vals <- list(NA=NA, NaN=NaN, Inf=Inf, 'NULL-in-vec'=c(1,NULL,3)[2])
for (name in names(special_vals)) {
  v <- special_vals[[name]]
  cat(name, '| is.na:', is.na(v), '| is.nan:', is.nan(v[!is.infinite(v)]), '
')
}
免费开始

用 AI 导师学习 R — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
43
课程
159

常见问题解答

「理解 R 中的 NA」课时是免费的吗?

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

「理解 R 中的 NA」这节课中我会学到什么?

了解 NA 的含义、它为何会传播,以及它与 NULL 的区别 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 R Academy 需要有经验吗?

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

「理解 R 中的 NA」课时需要多长时间?

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

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

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

此课程中的所有课时

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