时间: 2018-07-17
教程:慕课网 《R语言基础》 讲师:Angelayuan
补充内容:subset和merge函数的使用
学习内容:课程第三章:构建子集
构建子集
1.向量的子集(基本方法)
在进行数据处理时,我们直接获得的数据为原始数据(raw dataset),大多数情况下,原始数据并不是我们可以直接使用的数据,在进行数据处理前我们需要对数据进行预处理,其中,很重要的一步就是构建子集。
构建子集有很多种方法:
[]:提取一个或多个相同类型的元素
[[]]:从列表或数据框中提取元素
$:按名字从列表或数据框中提取元素。
如:
> y <- c(1,4,7,2,4,7,1,8,5,8,3,7)
> y[7] # 返回y中的第7个元素
[1] 1
需要注意的是,R中向量的元素的顺序是从1开始排的。
> y[1:5] # 返回y中的第1-第5个元素
[1] 1 4 7 2 4
> y[y>5] # 返回y中大于5的元素
[1] 7 7 8 8 7
> y>5
[1] FALSE FALSE TRUE FALSE FALSE TRUE FALSE TRUE FALSE TRUE FALSE
[12] TRUE
可以看出,y>5得到的结果是,满足条件的为TRUE,不满足条件的为FALSE,y[y>5]返回的就是使[]里的条件为TRUE的元素。
> y[y>5 & y<8] # 返回y中大于5且小于8的元素
[1] 7 7 7
> z <- y>5 & y<8
> y[z]
[1] 7 7 7
> y[y<4 | y>7] # 返回y中小于4或大于7的元素
[1] 1 2 1 8 8 3
> y1 <- 1:4
> names(y1) <- c("a","b","c","d") # 将y1中元素分别命名为a,b,c,d
> y1
a b c d
1 2 3 4
> y1[2]
b
2
> y1["b"]
b
2
可以看出,除了根据元素的顺序返回元素内容外,还可以根据元素的名称返回
2.矩阵的子集
如:
> x <- matrix(c(1,5,23,4,9,3), nrow=2, ncol=3)
> x
[,1] [,2] [,3]
[1,] 1 23 9
[2,] 5 4 3
> x[2,3] # 返回矩阵x中第2行第3列的元素
[1] 3
> x[1,] # 返回矩阵x中第1行的元素
[1] 1 23 9
> x[,1] # 返回矩阵x中第1列的元素
[1] 1 5
> x[2,c(1,3)] # 返回矩阵x中第2行第3、4列的元素
[1] 5 3
> class(x[1,2])
[1] "numeric"
可以看出使用x[]的方式获得的子集类型默认是一个向量。
在x[]中加入”drop = FALSE”,使返回的内容是一个矩阵,”drop = FALSE”的意思是关掉返回向量的选择。例:
> x1 <- x[1,2, drop = FALSE]
> x1
[,1]
[1,] 23
> class(x1)
[1] "matrix"
3.数据框的子集
如:
在建立好数据框后,可以根据需要对数据框中元素重新赋值。
格式:数据框名$列名[列中元素的序号] <- 所赋的值
> x <- data.frame(v1=1:5, v2=6:10, v3=11:15)
> x
v1 v2 v3
1 1 6 11
2 2 7 12
3 3 8 13
4 4 9 14
5 5 10 15
> x$v3[c(2,4)] <- NA # 将数据框x中v3列中的第2、4行内容设为缺失值
> x
v1 v2 v3
1 1 6 11
2 2 7 NA
3 3 8 13
4 4 9 NA
5 5 10 15
> rownames(x) = c("a","b","c","d","e")
> x
v1 v2 v3
a 1 6 11
b 2 7 NA
c 3 8 13
d 4 9 NA
e 5 10 15
> x$v1
[1] 1 2 3 4 5
> x$a
NULL
可以看出$后只能说是列名,而不能是行名
> x[4,2] # 返回数据框x中第4行第2列的元素内容
[1] 9
> x[2]
v2
a 6
b 7
c 8
d 9
e 10
> x["v2"]
v2
a 6
b 7
c 8
d 9
e 10
可以看出,返回x[2]和返回x[“v2”],所得到的结果是一致的,v2是第2列的名称,x[“v2”]的意思为返回v2对应的列,也就是第2列,而x[2]的意思是返回x中的第二个元素,可以认为数据框中第i列为第i个元素。
> x[,2]
[1] 6 7 8 9 10
> x[,"v2"]
[1] 6 7 8 9 10
> class(x["v2"])
[1] "data.frame"
> class(x[,"v2"])
[1] "integer"
可以看出,x[“v2”]的意思是直接返回第2列,返回的内容依旧是一个数据框,x[,”v2”]的意思是返回第2列中所有行的元素的值,返回的是一个整数向量。
> x["a"]
Error in `[.data.frame`(x, "a") : object 'a' not found
> x["a",]
v1 v2 v3
a 1 6 11
> x[1,]
v1 v2 v3
a 1 6 11
> x[c("a","d"),]
v1 v2 v3
a 1 6 11
d 4 9 NA
> class(x["a",])
[1] "data.frame"
> class(x[1,])
[1] "data.frame"
> class(x[1,2])
[1] "integer"
可以看出,x[数字或名称]只能用于抽取列作为子集,若想抽取行作为子集,需要在[]内加入”,” ,如x[1,]或x[“a”,],且通过这种方式获得的子集类型为数据框。
> x[(x$v1<4 & x$v2>=8),] # 返回第1列小于4且第2列大于等于8的行
v1 v2 v3
3 3 8 13
> x[x$v1>2, ] # 返回第1列大于2的行
v1 v2 v3
3 3 8 13
4 4 9 NA
5 5 10 15
> x$v1>2 # 判断x的第1列中的各行是否大于2
[1] FALSE FALSE TRUE TRUE TRUE
可以看出,x的第1列中的各行中大于2的行数为3、4、5 。
> class(x$v1>2)
[1] "logical"
> which(x$v1>2)
[1] 3 4 5
> class(which(x$v1>2))
[1] "integer"
可以看出,which()函数返回了()内对象中TRUE所对应的元素序号,且输出内容是一个整数向量。
可以使用subset()函数选择子集,其作用是从某一个数据框中选择出符合某条件的数据或是相关的列,格式为subset(对象名,条件),且该函数选择的子集类型与原对象类型一致。
> x[which(x$v1>2),] # 返回第which(x$v1>2)行
v1 v2 v3
3 3 8 13
4 4 9 NA
5 5 10 15
> subset(x,x$v1>2) #返回x第1列中大于2的行
v1 v2 v3
3 3 8 13
4 4 9 NA
5 5 10 15
> class(subset(x,x$v1>2))
[1] "data.frame"
> subset(x,v2 == 7) # 选择x中第2列等于7的行
v1 v2 v3
b 2 7 NA
> subset(x,v2 == c(7,8))
[1] v1 v2 v3
<0 行> (或0-长度的row.names)
Warning message:
In v2 == c(7, 8) :
longer object length is not a multiple of shorter object length
> subset(x,v2 == 7 | v2 == 8)
v1 v2 v3
b 2 7 NA
c 3 8 13
可以看出,选择x中第2列等于7、8的行属于多条件查询,需要使用”|”连接
在subset函数中加入select项可以选择指定的列,例:
> subset(x,v2 == 7,select = c(v2,v3))
v2 v3
b 7 NA
> class(subset(x,v2 == 7))
[1] "data.frame"
> class(subset(x,v2 == 7,select = c(v2,v3)))
[1] "data.frame"
可以看出subset()函数选择的子集类型与原对象类型一致。
merge()函数的作用是从两个数据框中选择出条件相等的列组合成一个新的数据框,格式为merge(对象名,对象名,by=”列名”/列的序号),该函数只能按列的条件来选择,”by”后面只能跟列。
> df1 <- data.frame(name = c("aa","bb","cc"),age = c(20,29,30),sex = c("f","m","f"))
> df2 <- data.frame(name = c("dd","bb","cc"),age = c(40,35,36),sex = c("f","m","f"))
> df1
name age sex
1 aa 20 f
2 bb 29 m
3 cc 30 f
> df2
name age sex
1 dd 40 f
2 bb 35 m
3 cc 36 f
> merge(df1,df2,by="name")
name age.x sex.x age.y sex.y
1 bb 29 m 35 m
2 cc 30 f 36 f
>df3 <- data.frame(name = c("dd","bb","ee"),age = c(75,23,34),sex = c("f","m","f"))
> df3
name age sex
1 dd 75 f
2 bb 23 m
3 ee 34 f
> merge(df2,df3,by = "name")
name age.x sex.x age.y sex.y
1 bb 35 m 23 m
2 dd 40 f 75 f
> merge(df2,df3,by = 1)
name age.x sex.x age.y sex.y
1 bb 35 m 23 m
2 dd 40 f 75 f
> merge(df1,df2,df3,by = "name")
Error in fix.by(by.x, x) :
'by'一定得用数字,名字或逻辑值来指定一个或多个列
可以看出,merge()函数只能从两个数据框中选择,不能超过两个。
4.列表的子集
如:
使用x[“元素名”/元素序号]返回列表x的某一个或多个元素,返回的类型为列表。例:
> x <- list(id=1:4, height=170, gender="male")
> x
$`id`
[1] 1 2 3 4
$height
[1] 170
$gender
[1] "male"
> x[1]
$`id`
[1] 1 2 3 4
> x["id"]
$`id`
[1] 1 2 3 4
> x[c(1,3)]
$`id`
[1] 1 2 3 4
$gender
[1] "male"
> x[c("id","height")]
$`id`
[1] 1 2 3 4
$height
[1] 170
使用x[[“元素名”/元素序号]]或x$元素名称 返回x的元素的内容。例:
> x[[1]]
[1] 1 2 3 4
> x[["id"]]
[1] 1 2 3 4
> x$id
[1] 1 2 3 4
> class(x[1])
[1] "list"
> class(x[[1]])
[1] "integer"
> class(x$id)
[1] "integer"
可以看出,使用[]时返回的类型不变,而使用[[]]或$时,返回的类型是整数向量,因为使用这种方法返回的是去掉了属性的列表,列表为向量+属性。
> y <- "id"
> x[[y]]
[1] 1 2 3 4
> x$y
NULL
可以看出,使用[[]]时与使用$时,使用方法不同。
> x1 <- list(a = list(1,2,3,4), b = c("Monday","Tuesday"))
> x1
$`a`
$`a`[[1]]
[1] 1
$`a`[[2]]
[1] 2
$`a`[[3]]
[1] 3
$`a`[[4]]
[1] 4
$b
[1] "Monday" "Tuesday"
> x1[[1]][[2]] #返回第1个元素中的第2个元素的内容
[1] 2
> x1[[1]][2] #返回第1个元素中的第2个元素
[[1]]
[1] 2
> x1[[c(1,3)]] #返回第1个元素中的第3个元素的值
[1] 3
> x1[[c(2,2)]] #返回第2个元素中的第2个元素的值
[1] "Tuesday"
> class(x1[[1]][[2]])
[1] "numeric"
> class(x1[[1]][2])
[1] "list"
> class(x1[[c(1,3)]])
[1] "numeric"
可以看出,使用[[]][[]]和[c(,)]返回的是一个数值型对象,使用[[]][]返回的对象类型与原对象相同。
> l <- list(asdfghj = 1:10)
> l$asdfghj
[1] 1 2 3 4 5 6 7 8 9 10
> l$a
[1] 1 2 3 4 5 6 7 8 9 10
> l$ad
NULL
R具有不完全匹配的功能,$后的元素允许只输入前几个字符,而不用全部输入,但输入的字符必须连续且正确。
当使用[[]]的不完全匹配的功能时,需要在[[]]里加入” exact = FALSE “,该句的意思是取消精准匹配,即,允许不完全匹配。例:
> l[["a"]]
NULL
> l[["a",exact = FALSE]]
[1] 1 2 3 4 5 6 7 8 9 10
> l2 <- list(asdfghj = c(1,2,4,6), b = 1:2, aaa = 3:5)
> l2$a
NULL
> l2[["a", exact = FALSE]]
NULL
> l2$as
[1] 1 2 4 6
可以看出,使用不完全匹配功能时,输入的字符量需要使R能够判断出是哪一个名称,若两个及以上的名称均与输入的字符满足不完全匹配的条件,该功能便不能使用。
5.处理缺失值
如:
> x <- c(1,NA,2,NA,3)
> x[!is.na(x)] # 返回x中不是缺失值的元素
[1] 1 2 3
> st <- matrix(c(1,5,NA,23,4,NA,9,NA,3,21,NA,11), nrow=4, ncol=3)
> st
[,1] [,2] [,3]
[1,] 1 4 3
[2,] 5 NA 21
[3,] NA 9 NA
[4,] 23 NA 11
> st[!is.na(st)]
[1] 1 5 23 4 9 3 21 11
> class(st)
[1] "matrix"
> class(st[!is.na(st)])
[1] "numeric"
使用st[!is.na(st)]时,返回的对象类型为数值型,该程序的实质是按顺序将对象中不是缺失值的元素抽取出来,组成向量。
> y <- c("a","b",NA,"c",NA)
> z <- complete.cases(x,y)
> z
[1] TRUE FALSE FALSE FALSE FALSE
当x中第i个元素和y中第i个元素均不是缺失值时,complete.cases(x,y)的第i个元素为TRUE,否则为FALSE
使用head函数可以返回数据集的前几行,默认为前6行,例:
> x[z]
[1] 1
> y[z]
[1] "a"
> library(datasets) #datasets为R的一个包,其中包含了许多数据集
> head(airquality)
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
5 NA NA 14.3 56 5 5
6 28 NA 14.9 66 5 6
airquality是datasets包中的一个数据集。
> g <- complete.cases(airquality)
> g
[1] TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE TRUE FALSE FALSE TRUE
[13] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[25] FALSE FALSE FALSE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE
[37] FALSE TRUE FALSE TRUE TRUE FALSE FALSE TRUE FALSE FALSE TRUE TRUE
[49] TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[61] FALSE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
[73] TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE
[85] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
[97] FALSE FALSE TRUE TRUE TRUE FALSE FALSE TRUE TRUE TRUE FALSE TRUE
[109] TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE FALSE TRUE
[121] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[133] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[145] TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE
当数据集中第i行的所有元素均不是缺失值时,complete.cases(airquality)的第i个元素为TRUE,否则为FALSE。
> airquality[g,][1:10,]
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
7 23 299 8.6 65 5 7
8 19 99 13.8 59 5 8
9 8 19 20.1 61 5 9
12 16 256 9.7 69 5 12
13 11 290 9.2 66 5 13
14 14 274 10.9 68 5 14
可以看出,运行airquality[g,]可以返回airquality中使得g为TRUE的行,加上[1:10,]表示只显示其中前10行
6.向量化操作
如:
> x <- 1:5
> y <- 6:10
> x+y
[1] 7 9 11 13 15
> x/y
[1] 0.1666667 0.2857143 0.3750000 0.4444444 0.5000000
>
> x1 <- matrix(1:4, nrow=2, ncol=2)
> y1 <- matrix(rep(2,4), nrow=2, ncol=2)
rep(2,4)的意思是2重复4次,相当于c(2,2,2,2)。
> x1
[,1] [,2]
[1,] 1 3
[2,] 2 4
> y1
[,1] [,2]
[1,] 2 2
[2,] 2 2
> x1*y1
[,1] [,2]
[1,] 2 6
[2,] 4 8
> x1/y1
[,1] [,2]
[1,] 0.5 1.5
[2,] 1.0 2.0
> x %*% y
[,1]
[1,] 130
R中向量的运算与MATLAB中向量运算类似,x*y,x/y与MATLAB中一致,R中x%*%y相当于MATLAB中x./y。