R语言学习5-向量子集
在本课程中,我们将了解如何根据指定的条件从向量中提取元素。
例如,我们可能只对向量的前20个元素感兴趣,或者仅对非NA的元素感兴趣,或者对正数或与感兴趣的特定变量相对应的那些元素感兴趣。
现在有这么一个向量x,里面包含20个服从标准正态分布的数字和20个NA。
> x[1] NA NA NA -0.05108979 NA -0.02086817 -0.65883869 NA -0.76755803 -0.94629711 NA[12] NA 0.25171708 0.18031701 -0.37318508 -0.98855340 -1.68402326 NA NA NA -0.99748631 NA[23] NA NA NA -0.21191859 NA 0.61580651 0.15191893 -0.84210911 NA NA NA[34] -0.02113655 NA NA 0.03523937 1.77489019 -0.16145833 -1.51209270
在R中,想从向量里选择某些特定元素(即“子集”)的方式是,将“索引向量”放在向量名称后方括号中。比如x[1:10],就可以获得x向量的前10个元素。
> x[1:10][1] NA NA NA -0.05108979 NA -0.02086817 -0.65883869 NA -0.76755803 -0.94629711
索引向量有4种不同的形式-逻辑向量,正整数向量,负整数向量和字符串向量-我们将在本课程中分别介绍。
逻辑索引
让我们首先从逻辑向量开始。处理实际数据时,一种常见的情况是我们要提取向量中非NA的所有元素。回想一下上一节[1]中的is.na()函数,返回的是与向量x长度相同的逻辑向量,其中TRUES代表x中的NA值,FALSE代表非NA值。
那么x[is.na(x)]会返回什么结果?
> 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
我们可以看到,返回的全部是NA,正好与实际需求相反。这个时候,只要使用!进行取反操作就好了。
> y <- x[!is.na(x)]> y[1] -0.05108979 -0.02086817 -0.65883869 -0.76755803 -0.94629711 0.25171708 0.18031701 -0.37318508 -0.98855340 -1.68402326 -0.99748631[12] -0.21191859 0.61580651 0.15191893 -0.84210911 -0.02113655 0.03523937 1.77489019 -0.16145833 -1.51209270
返回的是我们一开始需求单。上述代码已经把结果赋值给了y,接下来还可以更具条件对y进行子集提取操作。比如y[y > 0]
> y[y > 0][1] 0.25171708 0.18031701 0.61580651 0.15191893 0.03523937 1.77489019
那我们为什么不一开始就使用x[x > 0]呢?让我们先看看x[x > 0]的结果。
> x[x > 0][1] NA NA NA NA NA NA NA 0.25171708 0.18031701 NA NA NA[13] NA NA NA NA NA 0.61580651 0.15191893 NA NA NA NA NA[25] 0.03523937 1.77489019
结果里会出现很多NA,这是为什么?还记得上一节提过的NA的实际意义吗?NA不代表真正的值,而仅仅是一个无意义的占位符。所以NA > 0也是无意思的,R只能原样返回NA。
将逻辑运算符与子集提取相结合,我们可以这样得到x中的正数。
> x[!is.na(x) & x > 0][1] 0.25171708 0.18031701 0.61580651 0.15191893 0.03523937 1.77489019
正整数索引
在上面的例子中,我们已经用x[1:10]来提取x的前10个元素。在R中第一个元素的索引是1,但在许多其他编程语言中,第一个元素的索引是0。
那如果想获取x中第3,第5,第7个元素应该是怎么做呢?这个时候,就可以用到c()函数了。
> x[c(3, 5, 7)][1] NA NA -0.6588387
我们目前对子集的操作都是在x的范围内的,如果我们要取x的0号元素会怎么样?
> x[0]numeric(0)
返回的是numeric(0)空值,注意空值不代表缺失值。虽然这个操作没有什么意义,但是R并不会阻止它。下面再让我们看看超出x长度的索引,比如x[3000]
> x[3000][1] NA
这次返回的是NA,是一个缺失值。同样,没有什么用,但是R不会阻止我们要求它。这应该是一个值得警惕的事情。我们应始终确保所要查找的内容在所使用向量的范围内。
负整数索引
现在考虑这样一个场景,我们想获取x中除了第2,第10个元素之外的元素,应该怎么做?构建一个40以内,除2、10以外的数字索引是一个相当麻烦的事情。
这时候就可以用到负整数索引,要满足上诉场景的代码:
> x[c(-2, -10)][1] NA NA -0.05108979 NA -0.02086817 -0.65883869 NA -0.76755803 NA NA 0.25171708[12] 0.18031701 -0.37318508 -0.98855340 -1.68402326 NA NA NA -0.99748631 NA NA NA[23] NA -0.21191859 NA 0.61580651 0.15191893 -0.84210911 NA NA NA -0.02113655 NA[34] NA 0.03523937 1.77489019 -0.16145833 -1.51209270
负整数索引还有另外一种写法,把-号写在c()函数前面:x[-c(2, 10)]。大家可以试试是否等价。
字符串索引
到目前为止,我们已经介绍了三种索引向量:逻辑,正整数和负整数。剩下的唯一类型需要我们引入“命名”元素的概念。
首先,我们创建一个对元素命名的向量。
> vect <- c(foo = 11, bar = 2, norf = NA)
如果我们直接输出这个向量,其中的每个元素都会有自己的名字。
> vectfoo bar norf11 2 NA
使用names()函数可以获取向量中的元素名。
> names(vect)[1] "foo" "bar" "norf"
还可以通过names()函数来对向量的元素命名。
> vect2 <- c(11, 2, NA)> names(vect2) <- c("foo", "bar", "norf")
现在我们可以使用identical()函数来比较vect和vect2是否相同。
> identical(vect, vect2)[1] TRUE
现在回到字符串索引的问题上来,如果我们要获取vect的第2个元素,可以怎么做?
> vect["bar"]bar2
同样,我们可以通过字符串获取多个元素,比如vect[c("foo", "bar")]。
小结
从向量提取子集,有4种索引。在不同的情况下,最好使用不同的方法。
•逻辑索引:通过逻辑表达式来获取;•正整数索引:希望获取向量范围内的元素;•负整数索引:可以排除向量范围内的某些元素;•字符串索引:对元素进行命名后,可以通过元素的命名获取元素
References
[1] 上一节: https://yantinger.com/6Da2A7Xqk/
