时间: 2018-07-16
教程:慕课网 《R语言基础》 讲师:Angelayuan
补充知识:使用matrix创建矩阵
学习内容:课程第二章:R语言的数据结构
数据结构
1.向量
向量有三种生成方式:vector函数、生成等差数列组成的数组、c函数。
如:
vector函数中第一部分为向量类型,如:”character”;第二部分为向量长度,如:length = 10:
> x <- vector("character",length = 10)
生成一个有四个元素,依次为1,2,3,4的整数型向量:
> x1 <- 1:4
c函数会将向量中元素强制转换为同一类型:
> x2 <- c(1,2,3,4)
> x3 <- c(TRUE,10,"a")
> x3
[1] "TRUE" "10" "a"
可以看出c函数将输入的第一个逻辑类型元素TRUE,第二个数值型元素10和第三个字符型元素”a”均转化为了字符型”TRUE”、”10”和”a”。
> x4 <- c("a","b","c")
> as.numeric(x4) # 将对象类型转化为数值型
[1] NA NA NA
Warning message:
NAs introduced by coercion
出现了警告信息:缺失值NA被引入,即x4中三个元素均转化为了缺失值NA,原因:R无法将字符转化为数字
> as.logical(x4) # 将对象类型转化为逻辑型
[1] NA NA NA
> as.character(x4) # 将对象类型转化为字符型
[1] "a" "b" "c"
> class(x1)
[1] "integer"
可以看出x1类型为整数型。
使用name函数给x1中添加名称,四个元素分别命名为a,b,c和d:
> x1 # 输出x1
[1] 1 2 3 4
> names(x1) <- c("a","b","c","d") # 对x中各元素进行命名
> x1 # 输出x1
a b c d
1 2 3 4
可以看出命名后,x1的输出结果与命名前不同,第一行为各元素名称,第二行为各元素的值
2.矩阵和数组
矩阵可以认为是向量+维度属性(nrow,ncol)。
矩阵有两种生成方式:使用matrix函数、将向量转化为矩阵。
数组可以是2维及以上,而矩阵只能2维。
使用array函数生成数组。
如:
生成一个3行2列的矩阵,nrow为行数,ncol为列数
> x <- matrix(nrow = 3,ncol = 2)
> x
[,1] [,2]
[1,] NA NA
[2,] NA NA
[3,] NA NA
可以看到,上述matrix函数生成了一个3行2列的空矩阵
按行填写只需要将方括号中的逗号位置改变,或者参照矩阵中方括号及数字的写法即可:
> x[,1]=c(1:3) # 第一列内容为1,2,3
> x[,2]=c(4:6) # 第二列内容为4,5,6
> x # 输出x
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
使用nrow函数和ncol函数可以查看对象的行数和列数:
> nrow(x)
[1] 3
> ncol(x)
[1] 2
生成一个2行3列的矩阵,矩阵中元素为1,2,3,4,5,6:
> x1 <- matrix(1:6,nrow = 3,ncol = 2)
> x1
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
可以看出,R默认按列将1~6填入矩阵。
在函数最后加入byrow=T这个参数,可以按行填入元素
> x2 <- matrix(1:6,nrow = 3,ncol = 2,byrow=T)
> x2
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
> dim(x1) # 输出x1的维度信息
[1] 3 2
可以看出,x1为3行2列的矩阵,输出结果中第一项为行数,第二项为列数
> attributes(x1) # 输出x1的属性信息
$`dim`
[1] 3 2
可以看出x1的属性信息只有一项,名称为dim维度,是个长度为2的向量
使用is.matrix函数可以判断对象是否为一个矩阵。例:
> x1[2,1] # 输出x1的第2行第1列
[1] 2
> is.matrix(x1)
[1] TRUE
> is.matrix(x1[1,1])
[1] FALSE
矩阵的第二种生成方法:先生成一个向量,对向量加上维度即为一个矩阵(按列):
> y <- 1:6
> dim(y) <- c(2,3)
> y
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
使用rbind函数和cbind函数可以将矩阵进行拼接,rbind为按行拼接,要求矩阵列数相同;cbind为按列拼接,要求矩阵行数相同。例:
> y2 <- matrix(1:6,nrow=2,ncol=3)
> rbind(y,y2)
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
[3,] 1 3 5
[4,] 2 4 6
> cbind(y,y2) #
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 3 5 1 3 5
[2,] 2 4 6 2 4 6
> A = c(1,3,5) #
> B = c(2,4,6) #
> C = c(8,10,12) #
> z <- as.matrix(cbind(A,B,C)) #
> z #
A B C
[1,] 1 2 8
[2,] 3 4 10
[3,] 5 6 12
可以看出,当我们已经有包含元素的向量时,可以使用as.matrix函数套cbind函数或rbind函数,将向量拼接为矩阵。
可以使用rownames函数和colnames函数对矩阵的行列进行命名:
> z1=matrix(1:9,nrow=3)
> rownames(z1) = c("A","B","C") # 对z1的3行分别命名为A,B,C
> colnames(z1) = c("D","E","F") # 对z1的3列分别命名为D,E,F
> z1
D E F
A 1 4 7
B 2 5 8
C 3 6 9
可以使用dimnames函数对矩阵的维度进行命名,该例子中dimnames()中套用了一个list函数,所得结果与上述使用rownames()和colnames()对行列进行命名的结果一致,dimnames必须是一个列表。例:
>z2=matrix(1:9,nrow=3,dimnames=list(c("A","B","C"),c("D","E","F")))
> z2
D E F
A 1 4 7
B 2 5 8
C 3 6 9
> z2=matrix(1:9,nrow=3,dimnames=c("A","B","C","D","E","F"))
Error in matrix(1:9, nrow = 3, dimnames = c("A", "B", "C", "D", "E", "F")) :
'dimnames' must be a list
> z2[-2.]
[1] 1 3 4 5 6 7 8 9
可以看出,该程序提取了z2中除了第2个元素以外的其他元素,并组成一个向量。矩阵在R中本质是一个向量,只是这个向量加了一个维度的属性,R中矩阵的元素顺序为按列排列,因此,第二个元素为第1列第2行的元素2。
使用array函数生成一个二维数组,第一维长度为4,第二维长度为6:
> t(z2) # 使用t函数对z2进行转置
A B C
D 1 2 3
E 4 5 6
F 7 8 9
> X <- array(1:24,dim = c(4,6))
> X
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 5 9 13 17 21
[2,] 2 6 10 14 18 22
[3,] 3 7 11 15 19 23
[4,] 4 8 12 16 20 24
可以看出,两位数组和矩阵没有区别。
> X1 <- array(1:24,dim = c(2,3,4))
> X1
, , 1
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
, , 2
[,1] [,2] [,3]
[1,] 7 9 11
[2,] 8 10 12
, , 3
[,1] [,2] [,3]
[1,] 13 15 17
[2,] 14 16 18
, , 4
[,1] [,2] [,3]
[1,] 19 21 23
[2,] 20 22 24
可以看出,生成一个三维数组,输出结果分别为第3维的第1个元素、第2个元素、第3个元素和第4个元素,由结果可以看出1:24的填入顺序为先填第三维的第1个元素,第1个元素中按列来填入,第1个元素填满后填第2个元素。
> y1<- 1:24
> dim(y1) <- c(2,3,4)
> y1
, , 1
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
, , 2
[,1] [,2] [,3]
[1,] 7 9 11
[2,] 8 10 12
, , 3
[,1] [,2] [,3]
[1,] 13 15 17
[2,] 14 16 18
, , 4
[,1] [,2] [,3]
[1,] 19 21 23
[2,] 20 22 24
可以看出,数组就是一个向量加上维度,所得对象与上述直接生成数组相同
3.列表
向量、矩阵、数组要求对象内元素类型相同。列表允许对象中各元素类型不同。使用list函数生成列表。
如:
对列表中元素进行命名有两种方式:使用names函数、生成列表时进行命名。
> l <- list("a",2,10L,3+4i,TRUE) # 使用list函数生成一个列表
> names(l)= c("a","b","c","d","e")
> l
$`a`
[1] "a"
$b
[1] 2
$c
[1] 10
$d
[1] 3+4i
$e
[1] TRUE
> l2 <- list(a="a",b=2,c=10L,d=3+4i,e=TRUE)
> l2
$`a`
[1] "a"
$b
[1] 2
$c
[1] 10
$d
[1] 3+4i
$e
[1] TRUE
使用names函数对列表中第i个元素中的各元素进行命名:
> l3 <- list(c(1,2,3),c(4,5,6,7))
> l3
[[1]]
[1] 1 2 3
[[2]]
[1] 4 5 6 7
> names(l3[[1]]) = c("a","b","c")
> l3
[[1]]
a b c
1 2 3
[[2]]
[1] 4 5 6 7
也可以使用names函数对列表中的元素命名:
> names(l3)=c("a","b")
> l3
$`a`
a b c
1 2 3
$b
[1] 4 5 6 7
4.因子
因子用于处理分类数据(有序数据和无序数据),因子的本质是整数向量+标签。使用factor函数建立因子。
如:
> x <- factor(c("famale","famale","male","male","famale"))
> x
[1] famale famale male male famale
Levels: famale male
> y <- factor(c("famale","famale","male","male","famale"),levels = c("male","famale"))
> y
[1] famale famale male male famale
Levels: male female
可以看出x和y的区别仅仅在于水平中两水平顺序不同,可以使用levels函数确定基线水平,基线水平在前。
> table(x) # 输出各水平数量
x
famale male
3 2
> unclass(x) # 去掉属性后的x
[1] 1 1 2 2 1
attr(,"levels")
[1] "famale" "male"
> class(x)
[1] "factor"
> class(unclass(x)) # 去掉属性后的x的类型为整数型
[1] "integer"
5.缺失值
缺失值的处理是数据分析中很重要的一部分。
在R中,缺失值有两种表示方式:NA和NaN。其中,NaN属于NA,NaN只能表示数字的缺失值,NA可以表示多种类型缺失值。
如:
使用is.na函数和is.nan函数判断对象中元素是否为缺失值。
> x <- c(1,NA,2,NA,3)
> is.na(x)
[1] FALSE TRUE FALSE TRUE FALSE
> is.nan(x)
[1] FALSE FALSE FALSE FALSE FALSE
> x1 <- c(1,NaN,2,NaN,3)
> is.na(x1)
[1] FALSE TRUE FALSE TRUE FALSE
> is.nan(x1)
[1] FALSE TRUE FALSE TRUE FALSE
6.数据框
数据框可以用来存储表格数据,其本质是各元素长度相同的列表,每一个元素代表一列数据,每一个元素的长度为数据框的行数,各元素类型可以不同。使用data.frame函数建立数据框。
如:
> df <- data.frame(id = c(1,2,3,4),name = c("a","b","c","d"),gender = c(TRUE,TRUE,FALSE,FALSE))
> df
id name gender
1 1 a TRUE
2 2 b TRUE
3 3 c FALSE
4 4 d FALSE
> nrow(df) # 查看df的行数
[1] 4
> ncol(df) # 查看df的列数
[1] 3
> df2 <- data.frame(id = c(1,2,3,4), score = c(80,86,90,100))
> df2
id score
1 1 80
2 2 86
3 3 90
4 4 100
使用data.matrix函数可以将每一元素类型相同的数据框强制转化为矩阵。例:
> data.matrix(df2)
id score
[1,] 1 80
[2,] 2 86
[3,] 3 90
[4,] 4 100
7.日期和时间
日期(Date)在R中存储的内容为日期距离1970-01-01的天数。使用Date函数或Sys.Date函数获得当前的系统日期(电脑显示的日期)。
时间(Time)有两种格式:POSIXct、POSIXlt。POSIXct为整数,常用于存入数据框。POSIXlt为列表,包含星期、年、月、日等信息。
时间(Time)在R中存储的内容为日期距离1970-01-01的秒数。使用Sys.time函数获得当前的系统时间。
如:
> x <- date() # 获取电脑当前的时间
> x
[1] "Mon Jul 16 20:06:18 2018"
> class(x)
[1] "character"
可以看出使用date函数得到的日期是以字符串的形式存储的。
> x2 <- Sys.Date() # 获取电脑当前的时间
> x2
[1] "2018-07-16"
> class(x2)
[1] "Date"
可以看出使用Sys.Date函数得到的日期的形式是“Date”。
> x3 <- as.Date("2015-01-01")
使用as.Daate函数将日期存储为”Date”类型,原日期格式为年-月-日。
使用weekdays函数、months函数和quarters函数获得日期对象更详细的信息,分别为日期的星期、月份和季度。例:
> weekdays(x3)
[1] "Thursday"
> months(x3)
[1] "January"
> quarters(x3)
[1] "Q1"
使用julian函数所得结果为对象日期距离1970年1月1日过去的天数。例:
> julian(x3)
[1] 16436
attr(,"origin")
[1] "1970-01-01"
格式为”Date”的日期可以进行加减。例:
> x4 <- as.Date("2016-01-01")
> x4-x3
Time difference of 365 days
as.numeric函数将日期加减结果(天数)转为数值。例:
> as.numeric(x4-x3)
[1] 365
> y <- Sys.time() # 获取当前的系统时间
> y
[1] "2018-07-16 20:08:07 CST"
> class(y)
[1] "POSIXct" "POSIXt"
可以看出,使用Sys.time函数获得的日期格式为POSIXct。
可以使用as.POSIXlt函数将日期对象格式转为POSIXlt。例:
> p <- as.POSIXlt(y)
> class(p)
[1] "POSIXlt" "POSIXt"
可以使用as.POSIXct函数将日期对象格式转为POSIXct。例:
> names(unclass(p)) # 获取时间的各元素名称,即查询时间的内容
[1] "sec" "min" "hour" "mday" "mon" "year" "wday"
[8] "yday" "isdst" "zone" "gmtoff"
> p$sec # 获取p的秒数,格式为对象名$元素名称
[1] 18.63993
> as.POSIXct(p)
[1] "2018-07-16 20:03:18 CST"
使用strptime函数可以将其他格式的字符串类型的时间转化为POSIXlt格式的时间。例:
> y1 <- "Jan 1,2015 01:01"
> z <- strptime(y1, "%B %d, %Y %H:%M")
> z
[1] NA
> Sys.setlocale("LC_TIME", "C");
> y1 <- "Jan 1,2015 01:01"
> z <- strptime(y1, "%B %d, %Y %H:%M")
> z
[1] "2015-01-01 01:01:00 CST"
> class(z)
[1] "POSIXlt" "POSIXt"
转换控制符 | 说明 | 转换控制符 | 说明 |
---|---|---|---|
%a | 星期几的简写形式 | %M | 分,00-59 |
%A | 星期几的全称 | %p | 上午或下午 |
%b | 月份的简写形式 | %S | 秒,00-60 |
%B | 月份的全称 | %u | 星期几,1-7 |
%c | 日期和时间 | %w | 星期几,0-6星期几,0-6 |
%d | 月份中的日期,0-31 | %x | 当地格式的日期 |
%H | 小时,00-23 | %X | 当地格式的时间 |
%I | 12进制小时钟点,01-12 | %y | 年份中的最后两位数,00-99 |
%j | 年份中的日期,001-366 | %Y | 年 |
%m | 年份中的月份,01-12 | %Z | 地理时区名称 |