一个数据处理的小示例
用书中的数据处理的例子,作为本章学习的实践总结:
一组学生参加了数学、 科学和英语考试。 为了给所有学生确定一个单一的成绩衡量指标, 需要将这些科目的成绩组合起来。另外, 你还想将前20%的学生评定为A, 接下来20%的学生评定为B, 依次类推。最后, 按字母顺序对学生排序。
数据如下表所示:
学生姓名 | 数学 | 科学 | 英语 |
---|---|---|---|
John Davis | 502 | 95 | 25 |
Angela Williams | 600 | 99 | 22 |
Bullwinkle Moose | 412 | 80 | 18 |
David Jones | 358 | 82 | 15 |
Janice Markhammer | 495 | 75 | 20 |
Cheryl Cushing | 512 | 85 | 28 |
Reuven Ytzrhak | 410 | 80 | 15 |
Greg Knox | 625 | 95 | 30 |
Joel England | 573 | 89 | 27 |
Mary Rayburn | 522 | 86 | 18 |
需要处理的问题可以拆分成3个:
- 各科成绩标准化;
- 总成绩按20%分段评级;
- 学生名称依据字母顺序排序;
步骤1
我们来依次解决问题,首先把表格数据转换成R中的数据框。
options(digits=2)
用于设定计算结果的有效位数。
Student <- c("John Davis", "Angela Williams", "Bullwinkle Moose",
"David Jones", "Janice Markhammer", "Cheryl Cushing",
"Reuven Ytzrhak", "Greg Knox", "Joel England",
"Mary Rayburn")
Math <- c(502, 600, 412, 358, 495, 512, 410, 625, 573, 522)
Science <- c(95, 99, 80, 82, 75, 85, 80, 95, 89, 86)
English <- c(25, 22, 18, 15, 20, 28, 15, 30, 27, 18)
roster <- data.frame(Student, Math, Science, English,
stringsAsFactors=FALSE)
> roster
Student Math Science English
1 John Davis 502 95 25
2 Angela Williams 600 99 22
3 Bullwinkle Moose 412 80 18
4 David Jones 358 82 15
5 Janice Markhammer 495 75 20
6 Cheryl Cushing 512 85 28
7 Reuven Ytzrhak 410 80 15
8 Greg Knox 625 95 30
9 Joel England 573 89 27
10 Mary Rayburn 522 86 18
步骤2
我们可以看到,三科成绩存在数量级级别的差距,直接进行求和运算显然不妥,我们需要对数据进行标准化,使其可以进行运算和比较。
R提供了一个scale
函数,将原始数据用单位标准差来表示, 而不是以原始的尺度来表示。
> z <- scale(roster[,2:4])
> z
Math Science English
[1,] 0.013 1.078 0.587
[2,] 1.143 1.591 0.037
[3,] -1.026 -0.847 -0.697
[4,] -1.649 -0.590 -1.247
[5,] -0.068 -1.489 -0.330
[6,] 0.128 -0.205 1.137
[7,] -1.049 -0.847 -1.247
[8,] 1.432 1.078 1.504
[9,] 0.832 0.308 0.954
[10,] 0.243 -0.077 -0.697
attr(,"scaled:center")
Math Science English
501 87 22
attr(,"scaled:scale")
Math Science English
86.7 7.8 5.5
步骤3
然后使用apply
函数将mean
函数分别运用到各行数据,计算每一行的均值来获得综合得分,并使用cbind
函数添加到原数据框中:
score <- apply(z, 1, mean)
roster <- cbind(roster, score)
roster
Student Math Science English score score
1 John Davis 502 95 25 0.56 0.56
2 Angela Williams 600 99 22 0.92 0.92
3 Bullwinkle Moose 412 80 18 -0.86 -0.86
4 David Jones 358 82 15 -1.16 -1.16
5 Janice Markhammer 495 75 20 -0.63 -0.63
6 Cheryl Cushing 512 85 28 0.35 0.35
7 Reuven Ytzrhak 410 80 15 -1.05 -1.05
8 Greg Knox 625 95 30 1.34 1.34
9 Joel England 573 89 27 0.70 0.70
10 Mary Rayburn 522 86 18 -0.18 -0.18
步骤4
然后使用quantile
函数按照20%
进行分段计算分位数:
y <- quantile(roster$score, c(0.8, 0.6, 0.4, 0.2))
> y
80% 60% 40% 20%
0.74 0.44 -0.36 -0.89
步骤5
然后使用逻辑运算符进行数据的重编码,将成绩重编码为等级字符,创建一个变量grade
:
roster$grade[roster$score >= y[1]] <- 'A'
roster$grade[y[1] > roster$score & roster$score >= y[2] ] <- 'B'
roster$grade[y[2] > roster$score & roster$score >= y[3] ] <- 'C'
roster$grade[y[3] > roster$score & roster$score >= y[4] ] <- 'D'
roster$grade[roster$score < y[4]] <- 'E'
roster
Student Math Science English score score grade
1 John Davis 502 95 25 0.56 0.56 B
2 Angela Williams 600 99 22 0.92 0.92 A
3 Bullwinkle Moose 412 80 18 -0.86 -0.86 D
4 David Jones 358 82 15 -1.16 -1.16 E
5 Janice Markhammer 495 75 20 -0.63 -0.63 D
6 Cheryl Cushing 512 85 28 0.35 0.35 C
7 Reuven Ytzrhak 410 80 15 -1.05 -1.05 E
8 Greg Knox 625 95 30 1.34 1.34 A
9 Joel England 573 89 27 0.70 0.70 B
10 Mary Rayburn 522 86 18 -0.18 -0.18 C
说明一下上面的语句,roster$grade
直接在数据集roster
中创建了一个新变量grade
,[roster$score >= y[1]]
是子集选取的语句,符合条件的子集被赋值。
步骤6
根据姓名的首字母排序问题,首先使用strsplit
函数将姓名进行拆分,分隔符为空格
,返回对象为列表
:
> name<- strsplit(roster$Student, split = " ")
> str(name)
List of 10
$ : chr [1:2] "John" "Davis"
$ : chr [1:2] "Angela" "Williams"
$ : chr [1:2] "Bullwinkle" "Moose"
$ : chr [1:2] "David" "Jones"
$ : chr [1:2] "Janice" "Markhammer"
$ : chr [1:2] "Cheryl" "Cushing"
$ : chr [1:2] "Reuven" "Ytzrhak"
$ : chr [1:2] "Greg" "Knox"
$ : chr [1:2] "Joel" "England"
$ : chr [1:2] "Mary" "Rayburn"
步骤7:使用函数sapply() 提取列表中各个成分作为Firstname和Lastname变量, "[" 是一个可以提取某个对象的一部分的函数,1和2指定位置。
Firstname <- sapply(name, "[", 1)
Lastname <- sapply(name, "[", 2)
roster <- cbind(Firstname, Lastname, roster[,-1])
Firstname Lastname Math Science English score score.1 grade
1 John Davis 502 95 25 0.56 0.56 B
2 Angela Williams 600 99 22 0.92 0.92 A
3 Bullwinkle Moose 412 80 18 -0.86 -0.86 D
4 David Jones 358 82 15 -1.16 -1.16 E
5 Janice Markhammer 495 75 20 -0.63 -0.63 D
6 Cheryl Cushing 512 85 28 0.35 0.35 C
7 Reuven Ytzrhak 410 80 15 -1.05 -1.05 E
8 Greg Knox 625 95 30 1.34 1.34 A
9 Joel England 573 89 27 0.70 0.70 B
10 Mary Rayburn 522 86 18 -0.18 -0.18 C
步骤7
最后,使用order
函数进行排序:
roster[order(Lastname,Firstname),]
Firstname Lastname Math Science English score score.1 grade
6 Cheryl Cushing 512 85 28 0.35 0.35 C
1 John Davis 502 95 25 0.56 0.56 B
9 Joel England 573 89 27 0.70 0.70 B
4 David Jones 358 82 15 -1.16 -1.16 E
8 Greg Knox 625 95 30 1.34 1.34 A
5 Janice Markhammer 495 75 20 -0.63 -0.63 D
3 Bullwinkle Moose 412 80 18 -0.86 -0.86 D
10 Mary Rayburn 522 86 18 -0.18 -0.18 C
2 Angela Williams 600 99 22 0.92 0.92 A
7 Reuven Ytzrhak 410 80 15 -1.05 -1.05 E
好了,到此,这个数据处理的实践例子就做完了。
到此为止,我觉得要入门R语言,看这本书到这里基本就可以了。R的基本语法、数据结构、处理数据的基本方式都涵盖了。后续在应用中需要什么包就再去学习。