数据集取子集
R拥有强大的索引特性,可以用于访问对象中的元素。也可利用这些特性对变量或观测进行选入和排除。
1.选入(保留)变量
manager <- c(1,2,3,4,5)
> date <- c("8/1/18","8/2/18","8/3/18","8/4/18","8/5/18")
> country <-c("US","US","UK","UK","UK")
> gender <- c("M","F","F","M","F")
> age <- c(32,45,25,39,99)
> q1 <- c(5,3,3,3,2)
> q2 <- c(4,5,5,3,2)
> q3 <- c(5,2,5,4,1)
> q4 <- c(5,5,5,NA,2)
> q5 <- c(5,5,2,NA,1)
>
> survey <- data.frame(manager,date,country,gender,age,q1,q2,q3,q4,q5,stringsAsFactors = FALSE)
> print(survey)
manager date country gender age q1 q2 q3 q4 q5
1 1 8/1/18 US M 32 5 4 5 5 5
2 2 8/2/18 US F 45 3 5 2 5 5
3 3 8/3/18 UK F 25 3 5 5 5 2
4 4 8/4/18 UK M 39 3 3 4 NA NA
5 5 8/5/18 UK F 99 2 2 1 2 1
数据框中的元素可以通过dataframe[row indices, column indices]这样的记号来访问的。
> q <- survey[,c(6:10)]
> print(q)
q1 q2 q3 q4 q5
1 5 4 5 5 5
2 3 5 2 5 5
3 3 5 5 5 2
4 3 3 4 NA NA
5 2 2 1 2 1
当然也可以根据列名来提取变量:
> Q <- survey[,c("q1","q2","q3","q4","q5")]
> Q
q1 q2 q3 q4 q5
1 5 4 5 5 5
2 3 5 2 5 5
3 3 5 5 5 2
4 3 3 4 NA NA
5 2 2 1 2 1
2.剔除(丢弃)变量
2.1 通过负号“-”和位置来筛选
> new <- survey[,c(-8,-9)] #丢弃第八第九列
> print(new)
manager date country gender age q1 q2 q5
1 1 8/1/18 US M 32 5 4 5
2 2 8/2/18 US F 45 3 5 5
3 3 8/3/18 UK F 25 3 5 2
4 4 8/4/18 UK M 39 3 3 NA
5 5 8/5/18 UK F 99 2 2 1
2.2 通过取反的方式
> x <- names(survey) %in% c("q3","q4")
> new2 <- survey[,!x]
> new2
manager date country gender age q1 q2 q5
1 1 8/1/18 US M 32 5 4 5
2 2 8/2/18 US F 45 3 5 5
3 3 8/3/18 UK F 25 3 5 2
4 4 8/4/18 UK M 39 3 3 NA
5 5 8/5/18 UK F 99 2 2 1
这种方法有一定技巧性,%in% c("q3","q4")
判断 q3、q4
是否在变量名里面,这一行整句返回逻辑型向量,q3,q4
位置为TRUE
,其他为FALSE
。
则最后返回C("FLASE","FLASE","TRUE","TRUE",...,"FALSE")
,!
将逻辑值取反,因此最后取得时候就将q3
和q4
剔除掉了。
2.3 设为未定义(NULL)
> survey <- within(survey,{
+ q3 <- NULL
+ q4 <- NULL
+ })
> print(survey)
manager date country gender age q1 q2 q5
1 1 8/1/18 US M 32 5 4 5
2 2 8/2/18 US F 45 3 5 5
3 3 8/3/18 UK F 25 3 5 2
4 4 8/4/18 UK M 39 3 3 NA
5 5 8/5/18 UK F 99 2 2 1
顺便复习了以下within()
函数。值得一提的是,NULL
和NA
是区别很大的。
- NA表示数据集中的该数据遗失、不存在。在针对具有NA的数据集进行函数操作的时候,该NA不会被直接剔除。
- NULL表示未知的状态。它不会在计算之中。
3. 选入观测(即选行,对照前面的选列)
选入观测,可以根据观测的序号来选择,也可以根据特定的条件来选择,请看以下代码:
#根据序号选取
> head3 <- survey[c(1:3),]
> print(head3)
manager date country gender age q1 q2 q5
1 1 8/1/18 US M 32 5 4 5
2 2 8/2/18 US F 45 3 5 5
3 3 8/3/18 UK F 25 3 5 2
#根据条件选取
> new3 <- survey[survey$age >= 40,]
> print(new3)
manager date country gender age q1 q2 q5
2 2 8/2/18 US F 45 3 5 5
5 5 8/5/18 UK F 99 2 2 1
这里我们介绍一个新的函数,which()
函数。which()
函数的功能在于取符合条件(返回逻辑向量为TRUE
)的向量的下标,因此我们可以通过以下语句获得性别为女性且年龄大于40岁的行进行观测:
> attach(survey)
> new4 <- survey[which(gender == "F" & age >= 40),]
> print(new4)
manager date country gender age q1 q2 q5
2 2 8/2/18 US F 45 3 5 5
5 5 8/5/18 UK F 99 2 2 1
> detach(survey)
为了更好理解which()
函数,进行以下实践:
# 新建一个数组a
> a=c(1,3,4,5,3,2,5,6,3,2,5,6,7,5,8)
# 取数组a中最大值的下标
> which.max(a)
[1] 15
# 取数组a中最小值的下标
> which.min(a)
[1] 1
# 取数组a中大于3值的下标
> which(a>3)
[1] 3 4 7 8 11 12 13 14 15
# 取数组a中等于3值的下标
> which(a==3)
[1] 2 5 9
> # 10到1的数组元素中在a中的元素的下标
> b <- which(10:1 %in% a)
> print(b)
[1] 3 4 5 6 7 8 9 10
4. subset()
函数
前面讲的方法都较为繁琐,其实只需一个subset
函数就可以解决所有问题。
subset
函数的以下三种应用方式:
subset(x, subset, ...)
subset(x, subset, select, drop = FALSE, ...) ##对于矩阵
subset(x, subset, select, drop = FALSE, ...) ##对于数据框
- x 表示操作对象
- subset 表示保留元素或者行列的逻辑表达式,对于缺失值用NA代替
- select 表示选取的范围
我们用subset()
函数来完成之前which函数的操作:
> new5 <- subset(survey,gender == "F" & age >= 40,select = manager:q5)
> print(new5)
manager date country gender age q1 q2 q5
2 2 8/2/18 US F 45 3 5 5
5 5 8/5/18 UK F 99 2 2 1
5. 随机抽样
在数据挖掘和机器学习领域,从更大的数据集中抽样是很常见的做法。sample()
函数可以从数据集中(有放回或无放回地)抽取大小为n的一个随机样本。
sample(x, size, replace = FALSE, prob = NULL)
sample.int(n, size = n, replace = FALSE, prob = NULL,
useHash = (!replace && is.null(prob) && size <= n/2 && n > 1e7))
- x: 整体数据
- size:抽取样本的数目,默认为x的长度
- replace:是否重复抽样,如果为FALSE(默认)表示不重复抽样,此时size不能大于x的长度;如果为TRUE,则是重复抽样,此时size允许大于x的长度
- prob:x中各元素被选中的概率,表示按一定比例抽取,不要求总和为1,只要求大于0即可;默认为NULL,即等概率抽取
我们再最后用一次survey
数据,加入我们要无放回地抽取两行,则可以通过以下代码实现:
#随机抽样
> sample1 <- survey[sample(1:nrow(survey),2,replace = FALSE),]
> print(sample1)
manager date country gender age q1 q2 q5
5 5 8/5/18 UK F 99 2 2 1
4 4 8/4/18 UK M 39 3 3 NA
需要注意的一点是,sample()
函数中的x
为向量。