【上一篇:74.关于原子向量的类型及长度】
【下一篇:76.关于向量取子集】
向量类型的强制转换
向量类型之间的强制转换包括两种形式:显示转换和隐式转换。显示转换的执行是通过一系列as.*函数,比如as.logical()、as.integer()、as.double()、as.character()。看到代码中包含了这些函数就很容易理解代码在做什么了。显示转换的使用频率也不是特别大,我们重点关注隐式转换。
隐式强制场景一
一种隐式强制发生的场景是:你在需要某种类型的向量的特定上下文中使用向量。
比如在数字统计函数上下文中使用logical vectors,则TRUE会被强制成1,FALSE会被强制成0。在if判断语句上下文中使用数字向量,数字0会强制成FALSE,其他数字会被强制成TRUE。在integer上下文中使用double vectors,后者也会被强制转换。例子如下:
# logical vectors用sum()统计返回TRUE的个数,用mean()返回TRUE的比例
> x <- sample(20, 100, replace = TRUE)
> (y <- x > 10)
[1] FALSE FALSE TRUE FALSE FALSE TRUE TRUE TRUE TRUE FALSE FALSE
[12] FALSE TRUE FALSE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE
[23] FALSE TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE
[34] TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE FALSE TRUE
[45] FALSE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE TRUE
[56] FALSE TRUE FALSE TRUE FALSE TRUE TRUE FALSE FALSE FALSE FALSE
[67] TRUE TRUE FALSE TRUE FALSE FALSE FALSE TRUE TRUE TRUE FALSE
[78] FALSE TRUE FALSE FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE
[89] TRUE TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE
[100] FALSE
> sum(y)
[1] 48
> mean(y)
[1] 0.48
# if语句中,条件只能是T或F,也就是逻辑上下文,length(x)返回一个正整数,所以被强制为T.
> if(length(x)){print("do somethng")}
[1] "do somethng"
# 这种方式更建议写成如下形式
> if(length(x)>0){print("do somethng")}
[1] "do somethng"
# 其中length(x)>0 返回TRUE
隐式强制场景二
当你使用c()函数构建包含不同类型数据的向量时(这句话是个悖论哈,因为向量只能包含一种类型,向量的类型属性是完整向量的类型,而不是向量中单个元素的类型),会发生强制转换。转换原则是:最复杂的类型会赢,也就是其他所有类型都会转换成最复杂的那种类型。向量类型的复杂程度排序是:logical < integer < double < character。
向量类型有关的测试函数
当需要选择某种类型的向量用于分析时,一种方法是用typeof()函数获得类型名进行判断,另一种方法是用一个可以返回TRUE或FALSE的测试函数:is.*系列函数(Base R)或is_*系列函数(purrr包)。比如:is.vector()、is.atomic()和is_vector()、is_atomic(),相比前者,purrr中的这两个函数更安全,Base R中的这两个函数有时候会产生令人惊讶的结果。
is.atomic()和is.vector()函数的用法如下:
is.atomic(x)
is.vector(x,mode="any")
当对象x是atomic type(也就是logical、integer、numeric[请注意,不是double]、complex、raw、character)或NULL时,is.atomic()返回TRUE。
is.vector()比is.atomic()多了一个限制:一个对象可以是atomic,但不能是vector。原因就在于is.vector()函数的mode参数。举个例子,x对象是logical,is.atomic(x)返回TRUE,但设置mode="integer"后,is.vector(x,mode="interger")只能返回FALSE。
is.vector()的mode参数默认是"any",它的可选项是typeof()能返回的所有mode。
is.vector()还有一个限制:只有当输入对象满足特定类型,且对象属性处理names没有其他任何属性时才能返回TRUE,这样的结果就是factor(因子)不是vector。个人理解这个限制反而更大一些。
向量元素的命名
向量中国各个元素也是可以有名字的。有两种方法:一种是在用c()构建向量时直接指定,另一种是用用setNames()函数(Base R)或set_names()函数(purrr包)。如下:
# c()函数
> c(x = 1, y = 2, z = 4)
x y z
1 2 4
# setNames()函数
> (va <- c(1,2,4))
[1] 1 2 4
> setNames(va,c("x","y","z"))
x y z
1 2 4
# set_names()函数
> purrr::set_names(va,c("x","y","z"))
x y z
1 2 4
setNames()和set_names()的用法如下:
setNames(object = nm, nm)
object是要命名的对象,默认为nm,也就是说你不指定object,则默认你指定的名字就是向量元素,
nm是名称向量,
下面两种写法等价,但明显后一种更简洁。
setNames(c("First", "2nd"),c("First", "2nd"))
setNames(nm = c("First", "2nd"))
*************************************************
set_names(x, nm = x, ...)
x是要命名的向量
nm是名称向量,默认为x,也就是说当你不指定第二个参数时,默认用x中的元素给元素命名
两者的区别是:
1)setNames()函数的nm参数是必选项,而set_names()默认用x本身的元素给x的元素命名,除非你指定nm=NULL(对named vector,也可以用unname()函数去掉向量元素的名字)。也因此,当你指定非NULL的nm时实际相当于重命名向量元素的名字。如下:
> set_names(1:10)
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
> set_names(1:10,nm=NULL)
[1] 1 2 3 4 5 6 7 8 9 10
# 重命名向量元素的名字
> set_names(1:10,nm=letters[1:10])
a b c d e f g h i j
1 2 3 4 5 6 7 8 9 10
2)当然,x中已有元素名称,还可以提供一个函数或公式来转换元素名称,此时...被传递给函数。如下:
set_names(1:10, ~ letters[seq_along(.)])
set_names(head(mtcars), toupper)
set_names(head(mtcars), paste0, "_foo")
网友评论