前言
在前面的R Base(1), 我们简单介绍R的向量(Vector), 并利用c()函数创建了一个向量。c()是一个非常常见并被大家熟知的函数,最为常见的方式就是利用c()创建向量
c(1, 2, "a", "b")
## [1] "1" "2" "a" "b
但是,c()函数真的只有创建向量这一个功能吗?创建向量真的是开发者开发c()函数的本意吗?
今天就让我们带着这两个疑问和大家一起来学习c()函数不常为人知的一面吧。
(一) 合并 (combine)
没错!c() 函数最正确的解读是Combine而不是Create。下面我们来看看两个例子
- 示例1 将值合并入向量
#letters是R语言内部的向量,所有的小写英文字母
a <- letters[1:3]
c(1, a)
## [1] "1" "a" "b" "c"
- 实例2 将值并入列表
a <- list(1:3)
c("a",1:3, a)
## [[1]]
## [1] "a"
##
## [[2]]
## [1] 1
##
## [[3]]
## [1] 2
##
## [[4]]
## [1] 3
##
## [[5]]
## [1] 1 2 3
Note: 通过上面两个示例,我们可以学习到: - 1. c()的默认的数据操作类型是向量。- 2. 当c()中存在list数据类型时,c()函数会将向量转换成list,并合并成一个新的list输出
(二) 输出形式优先级
从示例1我们能看到, 当c()同时存在数值向量和字符向量时, 数值向量会被转化成字符向量,最后输出一个字符向量,那优先级上我们能看到 numeric < character;
同理从示例2我们可以看到vector < list。
R的帮助文档中有给出明确的等级关系:
NULL < raw < logical < integer < double < complex
< character < list < expression。
这一段等级关系中实际包含了四种不同对象类型,NULL, Vector, List, Expression, 其中raw < logical < integer < double < complex < character都属于向量。在之后的高级语法中,我们会给大家详细介绍, 大家可以期待一下下哦!
(三)参数recursive
参数recursive的取值有TRUE/FALSE,当取值TURE时,其功能有点类似函数unlist()。但是unlist一个最大区别在于c本身的合并功能。
a <- list(1:3)c("a",1:3, a, recursive = TRUE)
## [1] "a" "1" "2" "3" "1" "2" "3"
unlist(c("a",1:3, a))
## [1] "a" "1" "2" "3" "1" "2" "3"
# unlist没有合并功能unlist("a", 1:3, a)
## [1] "a"
一些有趣的Tips
- 默认返回值是NULL
c()
# NULL
c(NULL, NULL)
# NULL
- 操作数据框(data.frame)的有趣之处
c(head(mtcars))
## $mpg
## [1] 21.0 21.0 22.8 21.4 18.7 18.1
##
## $cyl
## [1] 6 6 4 6 8 6
##
## $disp
## [1] 160 160 108 258 360 225
##
## $hp
## [1] 110 110 93 110 175 105
##
## $drat
## [1] 3.90 3.90 3.85 3.08 3.15 2.76
##
## $wt
## [1] 2.620 2.875 2.320 3.215 3.440 3.460
##
## $qsec
## [1] 16.46 17.02 18.61 19.44 17.02 20.22
##
## $vs
## [1] 0 0 1 1 0 1
##
## $am
## [1] 1 1 1 0 0 0
##
## $gear
## [1] 4 4 4 3 3 3
##
## $carb
## [1] 4 4 1 1 2 1
Note: 为什么c()函数会将数据框转换成list进行输出了, 其根本原因在于数据框是一种特殊的list.
实际上,R的基本对象类型中并没有数据框这一个类型(type), 数据框更多可以理解成一种数据结构,或者类(class).
我们暂且不论这些, 因为这对于初学者或者user来说真的很难理解,并且这并不是我们今天的目的。
#mtcars是package datasets中的一个数据集。
typeof(mtcars)
## [1] "list"
is.list(mtcars)
## [1] TRUE
(五) c()的高级应用
接下来让我们用一个关于 c()的较为复杂的例子来结束今天内容吧。
案例是这样的:
如果某个变量不在数据框中,就返回一个其他的值。
library(dplyr, warn.conflicts = FALSE)
## Warning: 程辑包'dplyr'是用R版本4.3.2 来建造的
var_or_na <- function(x, fill = NA){
c(pick(any_of(x)), fill)[[1L]]
}
mtcars1 <- mtcars |>
mutate(a = var_or_na("m1", fill = "没有变量m1")) |>
select(a)
head(mtcars1)
head(mtcars1) :
mtcars2 <- mtcars |>
mutate(a = var_or_na("mpg", fill = "没有变量m1")) |>
select(mpg,a)
head(mtcars2)
head(mtcars2):
**Note:**这个函数需要你了解dplyr中的一些函数,如果你是一个刚入门的小白,可以忽略这个例子。这里只是想给大家体现c()函数的合并功能。
以上就是今天的简单分享, 后续也会进行R base, R for TLG 的分享。也欢迎大家关注公众号