R学习:R for Data Science 向量(2)
R学习往期回顾:
R学习 从Tidyverse学起,入门R语言 dplyr合并数据
R学习 从Tidyverse学起,入门R语言(tidyr和stringr)
R学习 从Tidyverse学起,入门R语言(tibble,readr和dplyr)
使用原子向量
我们已经弄清楚了不同类型的原子向量间的差别,接下来将讨论处理原子向量的几种重要操作,具体如下。 · 如何将一种原子向量转换为另一种,以及何时系统会自动转换。 · 如何分辨出一个对象是哪种特定类型的向量。 · 在处理长度不同的向量时,会发生什么情况。 · 如何命名向量中的元素。 · 如何提取出感兴趣的元素。
强制转换
当在特殊的上下文环境中使用向量,而这个环境又要求使用特定类型的向量时,就会发生隐式强制转换。例如,在数值型摘要函数中使用逻辑向量,或者在需要整型向量的函数中使用了双精度型向量时。
在数值环境中使用逻辑向量。这种情况下,TRUE 转换为 1, FALSE 转换为 0。这意味着对逻辑向量求和的结果就是其中真值的个数,逻辑向量的均值就是其中真值的比例:
x <- sample(20, 100, replace = TRUE)
y <- x > 10
sum(y) # 大于10的数有多少个?
#> [1] 49
mean(y) # 大于10的数的比例是多少?
#> [1] 0.49
检验函数
有时我们需要根据向量的类型进行不同的操作。检验向量类型的一种方法是使用 typeof()函数,另一种方法是使用检验函数来返回 TRUE 或 FALSE。R 基础包中提供了很多这样的函数,如 is.vector() 和 is.atomic(),但它们经常返回出人意料的结果。更可靠的方法是使用 purrr 包提供的 is_* 函数族,以下表格总结了它们的使用方式
循环规则
R 可以隐式地对向量类型进行强制转换,同样地,也可以对向量长度进行强制转换。这种转换称为向量循环,因为 R 会将较短的向量重复(或称循环)到与较长的向量相同的长度
如果两个长度相同的向量相加,或者一个向量和一个“标量”相加,那么结果是显而易见的,但是,如果两个长度不同的向量相加,那么会出现什么情况呢?
1:10 + 1:2
#> [1] 2 4 4 6 6 8 8 10 10 12
这里 R 会扩展较短的向量,使其与较长的向量一样长,这个过程就称作向量循环。这个过程是默默进行的,除非较长向量的长度不是较短向量长度的整数倍:
1:10 + 1:3
#>Warning message:
#>In 1:10 + 1:3 : 长的对象长度不是短的对象长度的整倍数
#>I[1] 2 4 6 5 7 9 8 10 12 11
向量命名
所有类型的向量都是可以命名的。你可以在使用 c() 函数创建向量时进行命名
c(x = 1, y = 2, z = 4)
#> x y z
#> 1 2 4
也可以在向量创建完成后,使用 purrr::set_names() 函数来命名
library(purrr)
set_names(1:3, c("a", "b", "c"))
#> a b c
#> 1 2 3
向量取子集
我们可以使用 dplyr::filter() 函数在 tibble 中筛选行。但 filter() 函数只能筛选 tibble,因此要想筛选向量,我们需要使用一个新工具:[。[ 就是取子集函数,调用形式是 x[a]。你可以使用以下 4 种形式来完成向量取子集操作
· 使用仅包含整数的数值向量。整数要么全部为正数,要么全部为负数,或者为 0。
使用正整数取子集时,可以保持相应位置的元素:
x <- c("one", "two", "three", "four", "five")
x[c(3, 2, 5)]
#> [1] "three" "two" "five"
位置可以重复,这样可以生成比输入更长的输出结果:
x[c(1, 1, 5, 5, 5, 2)]
#> [1] "one" "one" "five" "five" "five" "two"
使用负整数取子集时,会丢弃相应位置的元素:
x[c(-1, -3, -5)]
#> [1] "two" "four"
正数与负数混合使用则会引发一个错误:
x[c(1, -1)]
#> Error in x[c(1, -1)]:
#> only 0's may be mixed with negative subscripts
这条错误消息中提到了使用 0 来取子集,这样不会返回任何值:
x[0]
#> character(0)
· 使用逻辑向量取子集。这种方式可以提取出 TRUE 值对应的所有元素,一般与比较函数结合起来使用效果最佳:
x <- c(10, 3, NA, 5, 8, 1, NA)
# x中的所有非缺失值
x[!is.na(x)]
#> [1] 10 3 5 8 1
# x中的所有偶数值(或缺失值)
x[x %% 2 == 0]
#> [1] 10 NA 8 NA
· 如果是命名向量,那么可以使用字符向量来取子集:
x <- c(abc = 1, def = 2, xyz = 5)
x[c("xyz", "def")]
#> xyz def
#> 5 2
与使用正整数取子集一样,你也可以使用字符向量重复取出单个元素。
· 取子集的最简方式就是什么都不写:x[],这样就会返回 x 中的全部元素。这种方式对于向量取子集没有什么用处,但对于矩阵(或其他高维数据结构)取子集则非常重要,因为这样可以取出所有的行或所有的列,只要将行或列保持为空即可。例如,如果 x 是二维的,那么 x[1, ] 可以选取出第 1 行和所有列, x[, -1] 则可以选取出所有行和除第1 列外的所有列。
公众号“生信小课堂”