山海之间

R语言学习5-向量子集

R语言学习5-向量子集
2020-05-19 · 7 min read
索引 R语言 教程

在本课程中,我们将了解如何根据指定的条件从向量中提取元素。

例如,我们可能只对向量的前20个元素感兴趣,或者仅对非NA的元素感兴趣,或者对正数或与感兴趣的特定变量相对应的那些元素感兴趣。

现在有这么一个向量x,里面包含20个服从标准正态分布的数字和20NA

> 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的所有元素。回想一下上一节中的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的范围内的,如果我们要取x0号元素会怎么样?

> 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)

如果我们直接输出这个向量,其中的每个元素都会有自己的名字。

> vect
 foo  bar norf 
  11    2   NA

使用names()函数可以获取向量中的元素名。

> names(vect)
[1] "foo"  "bar"  "norf"

还可以通过names()函数来对向量的元素命名。

> vect2 <- c(11, 2, NA)
> names(vect2) <- c("foo", "bar", "norf")

现在我们可以使用identical()函数来比较vectvect2是否相同。

> identical(vect, vect2)
[1] TRUE

现在回到字符串索引的问题上来,如果我们要获取vect的第2个元素,可以怎么做?

> vect["bar"]
bar 
  2

同样,我们可以通过字符串获取多个元素,比如vect[c("foo", "bar")]

小结

从向量提取子集,有4种索引。在不同的情况下,最好使用不同的方法。

  • 逻辑索引:通过逻辑表达式来获取;
  • 正整数索引:希望获取向量范围内的元素;
  • 负整数索引:可以排除向量范围内的某些元素;
  • 字符串索引:对元素进行命名后,可以通过元素的命名获取元素

本文首发于公众号:柠檬培养师(ID: yantinger90),欢迎关注!

Powered by Gridea,浙ICP备17039354号-1,© 2019 - 2020🍋