写在前面
各位小伙伴儿们好呀,(笔芯),我是船长,初来乍到,还请多多关照,后续我将陆续发布以R语言为主的学习笔记、心得,与大家共勉。 好了,闲话少说,赶紧来进入今日份的笔记吧!
数据结构总结
R拥有许多用于存储数据的对象类型:标量、向量、矩阵、数组、数据框、列表等。
(先来几个简单的调调胃口)
1.五大基础向量(数据类型)
1.1数值型(Numeric)
即数值类型数据,如100、3.0、-2、-3.2等。
还有一个与数值型向量关系非常紧密的向量叫整型(Integer),但整型一般被归为数值型的子类型。数值型的显著特征是,数字没有小数部分,其后都跟有“L”的后缀标识:
2L,34L,0L 等。
1.2逻辑型(logical)
即TRUE与FALSE,值得注意的是,在必要情况下,解释器会自动把逻辑值与转换为数值:
print(TRUE+2+FALSE)
其输出为:
[1] 3
其原因是上述代码在执行时候,解释器会自动将TRUE、FALSE分别替换为数值型向量1和0,以确保代码继续执行。
抑或是将数值型替换为逻辑型:
if(5.2){
print("hello")
}else{
print("你好")
}
其输出为:
[1] "hello"
原因是在执行逻辑表达式判断的时候,所有非0的数值型均视为TRUE,0视为FALSE。
1.3 字符型(Character)
由一个或多个字母、字符(包括数字字符)组成,其外侧有单引号或双引号标识:
‘a’、“a” (二者等价)
“123”、“a1b2” 等
**PS:"123"是字符型,123是数字型,二者是不同类型。
此外,数字字符型与数字型进行四则运算解释器不会将数字字符转换为数字,如 :
print(2*"3")
与其他语言不同,解释器既不会将"3"转为数字型3从而输出6,也不会同python等一样复刻字符输出"33”.
1.4原型(Raw)
即字节型。
使用charToRaw()函数可生成原型向量。
a<-charToRaw("hello")
print(a)
输出:
[1] 68 65 6c 6c 6f
显然,原型即将字符以ASCII码(输出为十六进制)形式存储。
1.5复数型(Complex)
即虚数。
a<-1+2i
print(a)
输出:
[1] 1+2i
PS:若要查看向量类型,可使用class()函数。
print(class(2+3i))
输出:
[1] "complex"
2.组合向量(Vectors)
函数c()可用来创建包含多个同类型基础向量的向量组,称为vectors向量。
a<-c(1,2,3,4)
print(class(a))
b<-c("a","b","c")
print(class(b))
输出:
[1] "numeric"
[1] "character"
显然,变量a、b分别被赋值为数值型和字符型向量。
PS:每个向量都只能包含一类基础向量。例如如下创建向量都是错误的:
e<-c(1,"a",TRUE)
f<-c(2020,"2020")
组合向量的元素访问
对于含有多个元素的向量,有时候我们只需要访问其中的一个或部分元素,可以用如下方法实现:
#以向量a为例
a<-c('h','e','l','l','o')
#访问第三个元素
print(a[3])
#访问第一个和第四个元素
print(a[c(1,4)])
#访问第二至第五个元素
print(a[c(2:5)])
输出:
[1] "l"
[1] "h" "l"
[1] "e" "l" "l" "o"
3.标量
对于如:
f<-3
e<-"a"
h<-"hello"
g<-TRUE
等只包含一个元素的向量,称之为标量,他们主要用于保存常量。
写在中间 好了,品尝了三个小点心,现在开始吃正餐了(坏笑)。
4.列表(List)
组合向量虽然能够将多个基础向量赋值给变量,但在需要对多类型向量组做处理的时候,c()函数显然不够用了,列表就是用来解决此类问题的一维R对象。由list()函数创建:
# Create a list.
list1 <- list(c(2,5,3),21.3,"hello R")
# Print the list.
print(list1)
输出:
[[1]]
[1] 2 5 3
[[2]]
[1] 21.3
[[3]]
[1] "hello R"
列表list1包含了三个元素,他们的类型可以不同。
PS:值得注意的是,列表中的元素可以是矩阵、数组、因子等复杂类型的一种。
列表元素的访问
当然,与组合向量类似,对于列表也可以用同样的方法访问其中的部分元素:
print(list1[2])
print(list1[c(2,3)])
print(list1[c(1:3)])
输出:
[[1]]
[1] 21.3
#####分隔符
[[1]]
[1] 21.3
[[2]]
[1] "hello R"
#####分隔符
[[1]]
[1] 2 5 3
[[2]]
[1] 21.3
[[3]]
[1] "hello R"
是的,你没有看错。R中的下标不是从0开始,而是从1开始。
5.矩阵(Matrices)
矩阵是二维对象,每个元素必须是同类型,由matrix()函数创建:
# Create a matrix.
M = matrix( c('a','a','b','c','b','a'), nrow = 2, ncol = 3, byrow = TRUE)
print(M)
输出:
[,1] [,2] [,3]
[1,] "a" "a" "b"
[2,] "c" "b" "a"
该函数的nrow和ncol分别用于指定行数和列数,二者乘积必须与元素总数相等,否则会报错。二者也可只指定一个,解释器会自动求出另一个参数的值。byrow参数用于控制元素在矩阵中的填充方式,默认是列优先,即优先将列填充满。
M = matrix( c('a','a','b','c','b','a'), nrow = 2)
print(M)
上面代码仅指定了行数,填充方式为默认列优先,输出如下:
[,1] [,2] [,3]
[1,] "a" "b" "b"
[2,] "a" "c" "a"
PS:在如上的指定参数值时,应使用”=“而不是”<-“,尽管二者在多数情况下效果相同。关于二者的区别,这里引用一个较为公认的观点供大家参考:
通常“<-”被认为是赋值bai,”=”是传值。
在函数调用中,func(x=1)与func(x<-1)是有区别的,前者调用完后变量x不会被保留,而后者会在工作区里保留变量x=1。length(x=seq(1,10))计算完成后x不会被保留,而length(x<-seq(1,10))计算完后你会在工作区里发现x这个变量。
r言语通常用符号”<-”代替其它语言里的”=”来作赋值符号。
——百度知道
细心的读者一定观察到了,矩阵的输出,行值和列值都不是纯数字,行值之后和列值之前都带有逗号,记住了这一细节,那么接下来矩阵元素的访问你一定更得心应手。
矩阵下标的使用
从这开始就用交互式编辑界面了,省事
>#首先我们创建一个2x5的数字矩阵
> m=matrix(c(0:9),nrow=2)
> m
[,1] [,2] [,3] [,4] [,5]
[1,] 0 2 4 6 8
[2,] 1 3 5 7 9
> #访问第二行第三列元素
> m[2,3]
[1] 5
> #访问第1行所有元素
> m[1,]
[1] 0 2 4 6 8
> #访问第四列所有元素
> m[,4]
[1] 6 7
> #访问第1行的第二列和第五列的元素
> m[1,c(2,5)]
[1] 2 8
> #访问第二列的第三至第五列元素
> m[2,c(3:5)]
[1] 5 7 9
至此,我们已经了解了二维单类型数据对象的使用,如果数据维度超过二维,可以使用数组,如果数据有多种类型,可以使用数据框。
6.数组(Arrays)
数组是同一数据类型的多维集合,是矩阵的自然推广。
创建数组使用array()函数:
> a <- array(c(0:7),dim = c(2,2,2))
> a
, , 1
[,1] [,2]
[1,] 0 2
[2,] 1 3
, , 2
[,1] [,2]
[1,] 4 6
[2,] 5 7
也可以自定义数组的各维度值:
> a<-c('a1','a2','a3')
> b<-c('b1','b2','b3')
> c<-c('c1','c2','c3')
> #注意下面这条代码
> a<-array(1:100,c(3,3,3),dimnames=list(a,b,c))
> a
, , c1
b1 b2 b3
a1 1 4 7
a2 2 5 8
a3 3 6 9
, , c2
b1 b2 b3
a1 10 13 16
a2 11 14 17
a3 12 15 18
, , c3
b1 b2 b3
a1 19 22 25
a2 20 23 26
a3 21 24 27
以上代码在创建数组过程中,指定了101个元素,指定的数组维度是3x3x3,但并没有报错,从输出结果可以看到,在数组填充满之后,冗余元素全部被丢弃,反之,元素数量如果少于数组陈列数,元素会被循环填充。另外,数组维度与dimnames的参数长度必须严格相等,否则会报错。
访问数组元素与矩阵相同
7.数据框(Data Frame)
数据框(也称数据帧)是最贴近实际生活的数据结构,有多种数据类型(敲黑板,这节是重点中的重点)。
由函数data.frame()创建:
> BMI <- data.frame(
gender = c("Male", "Male","Female"),
height = c(152, 171.5, 165),
weight = c(81,93, 78),
Age = c(42,38,26)
)
> BMI
gender height weight Age
1 Male 152.0 81 42
2 Male 171.5 93 38
3 Female 165.0 78 26
数据框元素的访问
访问数据框元素主要有以下两种方式。二者略有不同。
1.如前述的下标访问方式:
> BMI[1]
gender
1 Male
2 Male
3 Female
> BMI[2:4]
height weight Age
1 152.0 81 42
2 171.5 93 38
3 165.0 78 26
2.美元符$,用于选取某个特定变量
> BMI$height
[1] 152.0 171.5 165.0
> table(BMI$height,BMI$Age)
> #table函数用于生成列联表
26 38 42
152 0 0 1
165 1 0 0
171.5 0 1 0
在实际使用中,对Data Frame对象的操作会非常频繁,attach()、detach()和with()这三个函数的功能将显得愈发重要,在后续的帖子中将展开详细介绍。
8.因子(Factors)
#boss当然是最后出场,最烧脑的来了。。。
1.因子将向量与向量中元素的不同值一起存储为标签。
2.factor()函数以一个整数向量的形式存储类别值。
#都是绕不过的概念,蓝瘦?先贴在这,慢慢看
因子在一开始确实不太容易理解,因子即数据的类别指标,将变量转化为因子相当于是对变量中的所有不相同元素按顺序关联为1,2,3…举例说明吧:
condition<-c('poor','good','nice','good')
name<-('kevin','frank','young','thor')
money<-(1,2,3,4)
condition明显与name变量不同,其元素是有序的,即’poor’,‘good’,'nice’存在递进关系,而名字却没有。
一般的,将诸如condition这类存在顺序关系的变量称为顺序型变量,而诸如name的变量称为类别型变量。而像money这种纯在严谨的变化顺序的变量,称为连续型变量。
在执行factor()函数后,condition、name、money分别被存储为(1,2,3,2)、(1,2,3,4)、
(1,2,3,4)
类别型和有序型变量称为因子。
以上是因子的定义,你可能一头雾水,不过你可以先简记下面的技巧,等你用的多了就会恍然大悟,”原来就TM你叫因子啊“。
通俗来讲就一句话,属于类别的变量转换为因子才有意义。
举个栗子:在某次的调查结果中,人名有很多,但我们不会以人名来分类,我们可能以性别、是否成年、职业等来分类或计数,这些量就可以转换为因子。
再贴上以为一位大佬的详解,希望对读者有帮助。
如何理解因子
因子实例:
> apple_colors <- c('green','green','yellow','red','red','red','green')
>
> # Create a factor object.
> factor_apple <- factor(apple_colors)
> factor_apple
[1] green green yellow red red red green
Levels: green red yellow
> nlevels(factor_apple)
[1] 3
其中,nlevels函数给出级别计数。
写在最后: 新人乍到,多多关照。 欢迎各位大佬批评指导。