【问题标题】:What does x[is.na(x)] do in R?x[is.na(x)] 在 R 中做了什么?
【发布时间】:2025-11-27 03:20:03
【问题描述】:

我正在关注swirl 教程,其中一个部分的向量 x 定义为:

> x
 [1]  1.91177824  0.93941777 -0.72325856  0.26998371          NA          NA
 [7] -0.17709161          NA          NA  1.98079386 -1.97167684 -0.32590760
[13]  0.23359408 -0.19229380          NA          NA  1.21102697          NA
[19]  0.78323515          NA  0.07512655          NA  0.39457671  0.64705874
[25]          NA  0.70421548 -0.59875008          NA  1.75842059          NA
[31]          NA          NA          NA          NA          NA          NA
[37] -0.74265585          NA -0.57353603          NA

然后当我们输入x[is.na(x)] 时,我们会得到一个包含所有NA 的向量

> x[is.na(x)]
 [1] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA

为什么会这样?我的困惑是is.na(x) 本身返回一个长度为 40 的向量,向量的每个条目中包含 TrueFalse,具体取决于该条目是否为 NA。为什么用 x[ ] “包装”这个向量突然变成NA 本身的子集?

【问题讨论】:

  • 当您按逻辑向量索引向量时,它会返回索引为TRUE 的向量元素。你可以自己玩这个——做x <- c(1, 2, 3),然后做x[c(T, F, T)]x[c(F, F, F)]等。
  • [] 运算符选择x 的子集。例如,x[1:4] 返回x 的前四个元素。当传递一个逻辑向量时,它会返回x 中向量为TRUE 的所有元素。所以x[is.na(x)] 返回x 的所有元素NA。相反,x[!is.na(x)] 将返回 x 的所有非NA 元素。

标签: r vector indexing idioms


【解决方案1】:

这称为逻辑索引。这是一个非常常见和简洁的 R 成语。

是的,is.na(x) 给出了一个与您的向量长度相同的布尔(“逻辑”)向量。

使用该逻辑向量进行索引称为逻辑索引

显然x[is.na(x)] 访问 x 中所有 NA 条目的向量,并且完全没有意义,除非您打算将它们重新分配给其他值,例如估算中位数(或其他)

 x[is.na(x)] <- median(x, na.rm=T)

注意事项:

  • x[!is.na(x)] 访问x 中的所有非NA 条目
  • 或者也可以与na.omit(x) 函数进行比较,后者更笨重
  • R 的内置函数过去(或不)处理 NA(默认或可自定义)的方式是一团糟,这就是为什么 x[is.na(x)] 成语如此重要)
  • 许多有用的函数 (mean, median, sum, sd, cor) 是 NA 感知的,即它们支持 na.rm=TRUE 选项来忽略 NA 值。见here。还有关于如何定义table_, mode_, clamp_

【讨论】: