R语言笔记之数据类型之向量

常见数据类型

R拥有许多用于存储数据的对象类型,包括标量、向量、矩阵、数组、数据框和列表。它们在存储数据的类型、创建方式、结构复杂度,以及用于定位和访问其中个别元素的标记等方面均有所不同。下图给出了这些数据结构的一个示意图:

查看数据类型

class()

使用class函数可以查看数据的类型,如下所示:

1
2
3
4
5
6
> x=c(1,2,3,4)
> class(x)
[1] "numeric"
> x1<-as.character(x)
> class(x1)
[1] "character"

数据类型转换

常用函数如下所示:

1
2
3
4
5
6
7
8
判断转换 类型转换函数
is.numeric() as.numeric()
is.character() as.character()
is.vector() as.vector()
is.matrix() as.matrix()
is.data.frame() as.data.frame()
is.factor() as.factor()
is.logical() as.logical()

使用如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> a <- c(1,2,3);a
[1] 1 2 3
> is.numeric(a)
[1] TRUE
> is.vector(a)
[1] TRUE
> a <- as.character(a)
> a #将a转化为字符串类型
[1] "1" "2" "3"
> is.numeric(a)
[1] FALSE
> is.vector(a)
[1] TRUE
> is.character(a)
[1] TRUE
> as.numeric(FALSE) #逻辑型数据转化为0与1
[1] 0
> as.numeric(TRUE)
[1] 1

向量

常见向量类型

向量可以是数值,字符,逻辑等,如下所示:

1
2
3
4
5
6
7
8
9
10
> a<-c(1,2,3,4,5,-3,-4);a #数值型向量
[1] 1 2 3 4 5 -3 -4
> b<-c("one","two","three");b #字符型向量
[1] "one" "two" "three"
> c<-c(TRUE,TRUE,TRUE,FALSE);c #逻辑型向量
[1] TRUE TRUE TRUE FALSE
> x<-c(5,4,2);x
[1] 5 4 2
> x[9]<-9;x # 当向量x不够长时,指定第9个元素为9,#自动将中间的元素补为NA
[1] 5 4 2 NA NA NA NA NA 9

向量的下标

向量的元素下标取值是以1开始,例如:要前例中取x向量中值为1,则为x[2],如果一个向量中有一个字符,则该向量的类型会变成字符,如下所示:

1
2
3
4
5
> demo_1<-c(1,2,'a')
> demo_1
[1] "1" "2" "a"
> mode(demo_1)
[1] "character"

向量的名称

1
2
3
4
5
6
> years <- c(1960,1964,1976,1994)
> years
[1] 1960 1964 1976 1994
> names(years)<-c("Kennedy", "Johnson", "Carter","Clinton");years
Kennedy Johnson Carter Clinton
1960 1964 1976 1994

向量元素的添加及合并

常用函数为c()append(),如下所示:

1
2
3
4
5
6
7
8
9
10
v1<-c(1,2,3);v1
v1_ft <- c(TRUE, TRUE, FALSE)
v1[v1_ft]
v2<-c(v1,55);v2
#格式为新向量<-(原向量,新元素)
## [1] 12 3 55
c(v2,v1) # 向量的合并
## [1] 12 3 55 12 3
append(v1,10,after=3) #在第3个向量后面加入10
## [1] 12 3 10

运行结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
> v1<-c(1,2,3);v1
[1] 1 2 3
> v1_ft <- c(TRUE, TRUE, FALSE)
> v1[v1_ft]
[1] 1 2
> v2<-c(v1,55);v2
[1] 1 2 3 55
> c(v2,v1) # 向量的合并
[1] 1 2 3 55 1 2 3
> ## [1] 12 3 55 12 3
> append(v1,10,after=3) #在第3个向量后面加入10
[1] 1 2 3 10

如果逻辑变量与数值在一起,则为转换成数值。TRUE转变成1 and FALSE 转变成 0,如下所示:

1
2
3
4
> demo_2<-c(1,2,TRUE);demo_2
[1] 1 2 1
> mode(demo_2)
[1] "numeric"

在R语言中没有单一的整数、单一字符的概念,例如:X<-2X<-'a';R都是当作向量来处理,只是这个向量只包括单一值。

向量批量序列的生成

seq()

用法:seq(length=, from=, to=)

length:指定生成个数;from:是指开始生成的点;to:截止点。如果不指定,则默认条件下:seq(N1,N2,BY=),其中,n1:开始位置;n2:截止位置;by=指定间隔,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
seq(length=10,from=10,to=100) # 生成从10到100的向量,一共10个
## [1]10 20 3040 50 6070 80 90 100
# 此命令等价于:
seq(10,100,10)
## [1]10 20 3040 50 6070 80 90 100
seq(1,10,by=2)
## [1] 1 3 5 7 9
seq(1,10,length=6)
## [1] 1.02.8 4.6 6.48.2 10.0
sequence(2:3) #产生以 2 和 3 结尾的序列数据
## [1] 1 2 1 2 3

rep()

用法:1. rep(P,N) 重复生成P值N次;2.rep(a1:a2,a1:a2) #重复a1到a2,按a1产生a1次,按a2产生a2次,如下所示:

1
2
3
4
5
6
rep(1,10)
## [1] 1 1 1 1 1 1 1 1 1 1
rep(1:5,each=2, times=2) #重复1到5,每个元素重复二次,整个数列重复两次
## [1] 1 1 2 2 3 3 4 4 5 5 1 1 2 2 3 3 4 4 5 5
rep(1:3,1:3) # 1重复1次,2重复2次,3重复3次
## [1] 1 2 2 3 3 3

向量索引

取子向量:通过下标实现

取某个元素:x[2];(如果X包括名称,注意:x[2]与x[[2]]的区别;

取某中几个:x[c(1,2,0)]

取某个/几个元素,利用-:x[-n]

向量排序

sort(); 输出排序后的结果;order();输出排序后的各个向量位置,如下所示:

1
2
3
4
5
6
a<-c(3,9,0,12,19)
sort(a)
## [1] 03 9 12 19
order(a)
## [1] 3 1 2 4 5
a<-c(3,9,0,12,19)

向量运算

相加

1
2
3
4
5
6
7
8
9
> Demo_5 <- 1:3;Demo_5
[1] 1 2 3
> Demo_6 <- 2:5;Demo_6
[1] 2 3 4 5
> Demo_7 <- Demo_6+ Demo_5;Demo_7
Warning message:
In Demo_6 + Demo_5 :
longer object length is not a multiple of shorter object length
[1] 3 5 7 6

向量:提取满足某一条件的向量

常见用法如下所示:

1
2
3
4
5
6
7
8
9
x[n] 第n个元素
x[-n] 除了第n个元素的x
x[1:n] 前n个元素
x[-(1:n)] 第n+1至最后的元素
x[c(1,4,2) ] 指定元素
x["name"] 名为"name"的元素
x[x > 3] 所有大于3的元素
x[x > 3 & x < 5] 区间(3,5)的元素
x[x %in% c ("a","and","the")] 给定组中的元素

具体案例使用如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
x<-c(10:1);x
## [1] 109 8 76 5 43 2 1
x[x==3]<-25;x #将x中等于3的元素变为25
## [1] 109 8 76 5 4 252 1
x[x=1]<-12;x #将x的第1个元素数值变为12
## [1] 129 8 76 5 4 252 1
letters[1:30] # 产生字母序列
## [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q"
## [18] "r" "s" "t" "u" "v" "w" "x" "y" "z" NA NA NA NA
a <- c(2,3,4,2,5,1,6,3,2,5,8,5,7,3);a
## [1] 2 3 4 2 5 1 6 3 2 5 8 5 7 3
which.max(a) # 找出最大元素的下标
## [1] 11
which.min(a) # 找出大小的元素下标
## [1] 6
a[which.max(a)] # 找出最大的元素
## [1] 8
which(a==2) # 等于2的元素的下标
## [1] 1 4 9
a[which(a==2)] # 等于2的元素
## [1] 2 2 2
which(a>5) # 大于5的元素的下标
## [1] 7 11 13
a[which(a>5)] # 大于5的元素
## [1] 6 8 7

再看一案例

1
2
3
4
5
6
7
> data <- 1:100
> data[data > 20]
# 取data 中大于20 的对象出来
[1] 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
[25] 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
[49] 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
[73] 93 94 95 96 97 98 99 100

通过方括号中的data > 20 ,实现了我们想要的效果,具体是如何实现的呢?

1
2
3
4
5
6
7
8
> data > 20
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[17] FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[33] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[49] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[65] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[81] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[97] TRUE TRUE TRUE TRUE

data > 20 是一个表示式,它的返回值是一个有TRUE和FALSE 构成的逻辑向量,最终只选取了TRUE对应的元素,所以data 中大于20的元素被选了出来。通过下标和逻辑值两种方式,可以满足我们绝大部分的需求,但是有时候,我们只是想知道符合条件的值对应的下标,这个时候which 函数就派上了用场,如下所示:

1
2
> which(letters == "a")
[1] 1

==操作符用来判断字符串相等,which 函数返回对应的下标,letters 这个向量中,第一个元素就是字母a, 所以返回值为1,如下所示:

1
2
3
4
5
> letters
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x"
[25] "y" "z"
> which(letters %in% c("a", "d", "e"))
[1] 1 4 5

%in%操作符用来判断操作符左边的向量中的元素是否位于操作符右边的向量中,通过这种集合操作,可以方便的一次返回多个下标,使用subset函数也可以提取满足某一条件的向量元素,如下所示:

1
2
3
4
5
> x <- c(1,3,8,2,20)
> x
[1] 1 3 8 2 20
> subset(x,x>5)
[1] 8 20

ifelse

1
2
3
4
> x <- c(1,1,1,0,0,1,1);x
[1] 1 1 1 0 0 1 1
> ifelse(x != 1, 1, 0) #若果x的值不等于1,输出1,否则输出0
[1] 0 0 0 1 1 0 0

ifelse和%in%的联合使用,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> ifelse(x %in% 1, 1, 0) #若x的值包含在1里面,输出1,否者输出0
[1] 1 1 1 0 0 1 1
> ifelse(x %in% 1, 'yes', 'no') #若x的值包含在1里面,输出yes,否者输出no
[1] "yes" "yes" "yes" "no" "no" "yes" "yes"
> which(x %in% 1) # 输出x包含在1中值的位置
[1] 1 2 3 6 7
> y <- c(2, 1, 3, 4)
> z <- c(1, 4)
> ifelse(y %in% z, which(y==z), 0 ) ##若y的值包含在z里面,输出y==z的位置,否者输出0
[1] 0 4 0 4
> ifelse(y %in% z, which(y==z), 0 ) ##若y的值包含在z里面,输出y==z的位置,否者输出0,
[1] 0 4 0 4
> #此例中没有找到y==z的值, 输出为NA。
> ifelse(y %in% z, 1, 0 )
[1] 0 1 0 1

向量的比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
x<-c(1,2,3)
y<-c(1,2,3)
z<-c(1,2,4);
x;y;z
## [1] 1 2 3
## [1] 1 2 3
## [1] 1 2 4
x==y;x==z;y==z #分别比较x,y,z的各个元素
## [1] TRUE TRUE TRUE
## [1] TRUETRUE FALSE
## [1] TRUETRUE FALSE
identical(x,y);identical(x,z);identical(z,y) #比较x,y,z的整体
## [1] TRUE
## [1] FALSE
## [1] FALSE
all.equal(x,y) #比较数值型变量是否“近似相等”
## [1] TRUE

两组数据的集合运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
> #首先对集合A,B,C赋值
> A<-1:10
> B<-seq(5,15,2)
> C<-1:5
> union(A,B)#求A和B的并集
[1] 1 2 3 4 5 6 7 8 9 10 11 13 15
> intersect(A,B) #求A和B的交集
[1] 5 7 9
> setdiff(A,B) #求A-B
[1] 1 2 3 4 6 8 10
> setdiff(B,A) #求B-A
[1] 11 13 15
> setequal(A,B) # 检验集合A,B是否相同
[1] FALSE
> is.element(12,C) #检验元素12是否属于集合C
[1] FALSE
> all(C%in%A) #检验集合A是否包含C
[1] TRUE
> all(C%in%B)
[1] FALSE
> match(C,B)
[1] NA NA NA NA 1

从上面可以看到%in%这个操作符只返回逻辑向量TRUE 或者FALSE,而且返回值应该与%in%这个操作符前面的向量程度相等。也就是说它相当于遍历了C里面的一个个元素,判断它们是否在B中出现过,然后返回是或者否即可。而match(C,B)的结果就很不一样了,它的返回结果同样与前面的向量等长,但是它并非返回逻辑向量,而是遍历了C里面的一个个元素,判断它们是否在B中出现过,如果出现就返回在B中的索引号,如果没有出现,就返回NA,还来看一个match()的案例,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
A<-1:10
B<-seq(5,15,2)
C<-1:5
A
B
C
match(A,B) #遍历A中的元素,看A的元素是否在B里面出现过,如果A中的元素在B中出现,就返回此元素在B中的索引号
match(B,A)
match(A,C)
match(C,A)
match(B,C)
match(C,B)

运行结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> A
[1] 1 2 3 4 5 6 7 8 9 10
> B
[1] 5 7 9 11 13 15
> C
[1] 1 2 3 4 5
> match(A,B)
[1] NA NA NA NA 1 NA 2 NA 3 NA
> match(B,A)
[1] 5 7 9 NA NA NA
> match(A,C)
[1] 1 2 3 4 5 NA NA NA NA NA
> match(C,A)
[1] 1 2 3 4 5
> match(B,C)
[1] 5 NA NA NA NA NA
> match(C,B)
[1] NA NA NA NA 1