1.准备工作
library(tidyverse)
#> ── Attaching packages ────────────────────────────────────────────────────────────────────── tidyverse 1.2.1 ──
#> ✔ ggplot2 3.0.0 ✔ purrr 0.2.5
#> ✔ tibble 1.4.2 ✔ dplyr 0.7.6
#> ✔ tidyr 0.8.1 ✔ stringr 1.3.1
#> ✔ readr 1.1.1 ✔ forcats 0.3.0
#> ── Conflicts ───────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
#> ✖ dplyr::filter() masks stats::filter()
#> ✖ dplyr::lag() masks stats::lag()
#需要用到其中的purrr
2.向量的分类
一直以为向量就是c(),现在发现类型很多哇。
(1)NULL
首先不认识的是NULL,长度为零。也就是啥都没有的空向量。与NA不同,NA还是有长度的!
length(NA)
#> [1] 1
length(NULL)
#> [1] 0
如果正常所熟知的向量是种在坑里的萝卜。那么NA就只是没萝卜,而NULL则是没坑的!
(2)原子向量,就是平常所熟知的c()
- 逻辑型
- 数值型
- 整型
- 双精度型
- 字符型
- 负数型和原始型暂不学习。
(3)列表
对list早有耳闻,今天才知道它就是“递归向量”,可以嵌套的。
了解向量类型和长度,方法:
class(letters)
#> [1] "character"
typeof(letters)
#> [1] "character"
#对列表做一个尝试,同样的几个元素用c和list分别组合,他们的长度是不同滴!
x <- c("a", "b", 1:10)
length(x)
#> [1] 12
x2 <- list("a", "b", 1:10)
length(x2)
#> [1] 3
3.重要的原子向量
(1)最简单-逻辑型
只有 3 个可能的取值: FALSE、 TRUE 和 NA。
(2)数值型
整型和双精度型的比较和区别
typeof(1)#默认是双精度型
#> [1] "double"
typeof(1L)#指定为整型
#> [1] "integer"
#双精度型是近似值
sqrt(2) ^ 2==2
#> [1] FALSE
dplyr::near(sqrt(2) ^ 2,2)
#> [1] TRUE
特殊值
双精度型数据有4个特殊值: NA、 NaN、 Inf 和 -Inf
翻译过来就是,空值,非数字,正无穷,负无穷
用is.finite()、 is.infinite() 和is.nan()鉴定类型。
我小学老师好像说过,0为分母就是无意义的数字。可是刚才试了下:
is.nan(3/0)
#> [1] FALSE
#居然false。那么他是啥?
3/0
#> [1] Inf
#好的,受教了,他是无限值。
(3)字符型
R对每个唯一的字符串只保存一次,节省内存。
#算法
x <- "This is a reasonably long string."
pryr::object_size(x)
#> 152 B
#1000倍应该是136kb
y1 <- rep(x, 500)
y2 <- rep(x, 1000)
pryr::object_size(y1)
#> 4.14 kB
pryr::object_size(y2)
#> 8.14 kB
#实际上小很多,y 中的每个元素都只是指向一个字符串的指针,大小8B
#所以算法是y1: 8 * :500 + 136=4136B=4.14kb
#y2:8 * 1000 + 136=8136B=8.14kb
(4)缺失值
NA居然还分类型。记下来:
NA
#> [1] NA
NA_integer_
#> [1] NA
NA_real_
#> [1] NA
NA_character_
#> [1] NA
4.使用原子向量
(1)强制转换
- 显式转换
as.logical()、 as.integer()、 as.double() 、 as.character()、 - 隐式转换
在数值环境中使用逻辑向量,TRUE 转换为 1, FALSE 转换为 0。
所以sum成了计数,mean成了比例!
用c()将两种不同类型的元素放到一起,转换为最复杂的元素类型。
所以我回去看了一下刚才创建的x
x <- c("a", "b", 1:10)
typeof(x)
#> [1] "character"
#书上的另外几个例子
typeof(c(TRUE, 1L))
#> [1] "integer"
typeof(c(1L, 1.5))
#> [1] "double"
typeof(c(1.5, "a"))
#> [1] "character"
看过例子明白了“最复杂的”的意思,数字可以转换为字符,字符却不能转换为数字。同样,双精度也无法转换为整数,能转化的就是软柿子啦,敌不动我动。
(2)检验函数-is.*
·················图片·················
(3)标量与循环规则
向量循环--对向量长度进行强制转换。
- R中的“标量”,是长度为1的向量。
- 向量与标量的例子:
sample(10)+100
#> [1] 104 106 103 105 107 109 108 101 102 110
runif(10) > 0.5
#> [1] TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE
#向量有多少个元素,就有多少个结果。
- 两个长短不同的向量
#不用书上的例子了,换个简单的。
1:4+1:2
#> [1] 2 4 4 6
#长是短的倍数,就默默循环,四个数字是1+1,2+2,3+1,4+2的出来的。
1:3+1:2
#> Warning in 1:3 + 1:2: longer object length is not a multiple of shorter
#> object length
#> [1] 2 4 4
#产生警告信息,告诉你不成对。
在tibble中则会直接报错,需要手动rep。
rep有两个用法:times和each。默认是times。
tibble(x = 1:4, y = rep(1:2, times = 2))#times不写也一样的。
#> # A tibble: 4 x 2
#> x y
#> <int> <int>
#> 1 1 1
#> 2 2 2
#> 3 3 1
#> 4 4 2
tibble(x = 1:4, y = rep(1:2, each = 2))
#> # A tibble: 4 x 2
#> x y
#> <int> <int>
#> 1 1 1
#> 2 2 1
#> 3 3 2
#> 4 4 2
(4)向量命名
在14章看到一个函数说是判断向量有没有名字。。嗯。这里讲怎么命名啦。
c(x = 1, y = 2, z = 4)
#> x y z
#> 1 2 4
set_names(1:3, c("a", "b", "c"))
#> a b c
#> 1 2 3
(5)向量取子集
- 按位置提取
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)] 不可以正负混合
- 用逻辑向量取子集
x <- c(1:10,NA)
x[x>4]
#> [1] 5 6 7 8 9 10 NA
x[!is.na(x)]#非空值
#> [1] 1 2 3 4 5 6 7 8 9 10
x[x %% 2 == 0]#偶数
#> [1] 2 4 6 8 10 NA
网友评论