R in Action学习笔记:一个简单的数据处理实例

这是来自《R in Action》中的一个数据处理实例。
数据:一组学生的名字和其对应的数学、科学、英语的成绩;

数据分析需求:

1、为所有学生确定一个单一的成绩衡量指标;
2、将前20%的学生评定为A,接下来20%的学生评定为B,依次类推;
3、按照学生姓氏的字母顺序对学生排序。

要考虑的问题:

1、由于各科成绩的均值和标准差相去甚远,所以这些成绩无法直接组合,对它们求平均值是没有意义的。在组合这些考试成绩之前,必须将其变换为可比较的单元;
2、为了评定等级,需要一种方法来确定某个学生在前述得分上百分比排名;
3、表示姓名的字段只有一个,这让排序任务复杂化了。为了正确地将其排序,需要将姓和名拆开。

学生成绩数据:

学生姓名 数学 科学 英语
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

用到的数据处理函数:

scale()函数
scale(x,center=TRUE, scale=TRUE)
为数据对象x按列进行中心化(center=TRUE)或标准化(center=TRUE,scale =TRUE);
默认情况下,函数scale()对矩阵或数据框的指定列进行均值为0、标准差为1的标准化: newdata <- scale(mydata)
要对每一列进行任意均值和标准差的标准化:newdata <- scale(mydata) * SD + M,其中M是想要的均值,SD为想要的标准差。

apply()函数
沿着数组的某一维度处理数据,apply(数组,维度,函数/函数名),第一个参数是指要参与计算的矩阵;第二个参数是指按照哪个维度进行计算,第三个参数是指具体的运算参数。

sapply()函数
可以循环处理列表中的每一个元素,sapply(列表,函数/函数名,其他参数),总是返回一个列表。

strsplit()函数
strsplit(x, split, fixed=FALSE) 在split处分割字符向量x中的元素。若fixed=FALSE,则 pattern为一个正则表达式。若fixed=TRUE,则pattern为一个文本字符串。例如,y <- strsplit(“abc”, “”)将返回一个含有1个成分、3个元素的列表,包含的内容为"a" “b” “c” 。

主要代码如下:
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)
# 创建数据框,使用参数stringsAsFactors = FALSE关闭R自动将字符串转换为因子Factor的功能。
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

# 计算综合得分,将各科成绩变量进行标准化,这样每科成绩都使用单位标准差来表示
z <- scale(roster[,2:4])

# 使用mean函数计算各行的均值,并使用cbind函数将其添加到花名册roster中
score <- apply(z,1,mean)
roster <- cbind(roster,score)

# 使用函数quantile计算学生综合得分的百分位数
y <- quantile(score,c(.8,.6,.4,.2))

# 使用逻辑运算符,将学生的百分位数排名重编码为一个新的类别型成绩变量
roster$grade[score >= y[1]] <- "A"
roster$grade[score < y[1] & score >= y[2]] <- "B"
roster$grade[score < y[2] & score >= y[3]] <- "C"
roster$grade[score < y[3] & score >= y[4]] <- "D"
roster$grade[score < y[4]] <- "F"

roster # 处理后的roster
student math science english score grade
1 John Davis 502 95 25 0.56 B
2 Angela Williams 600 99 22 0.92 A
3 Bullwinkle Moose 412 80 18 -0.86 D
4 David Jones 358 82 15 -1.16 F
5 Janice Markhammer 495 75 20 -0.63 D
6 Cheryl Cushing 512 85 28 0.35 C
7 Reuven Ytzrhak 410 80 15 -1.05 F
8 Greg Knox 625 95 30 1.34 A
9 Joel England 573 89 27 0.70 B
10 Mary Rayburn 522 86 18 -0.18 C

# 抽取姓氏和名字,strsplit函数应用到一个字符串组成的向量上会返回一个列表
name <- strsplit((roster$student)," ")
#  "["是一个可以提取某个对象的一部分的函数——在这里它是用来提取列表name各成分中的第一个或第二个元素
# 由于已经不再需要student变量,故将其丢弃(在下标中使用-1代表将第1列去掉) 
lastname <- sapply(name,"[",2)
firstname <- sapply(name,"[",1)
roster <- cbind(firstname,lastname,roster[,-1])
# 使用函数order()依姓氏和名字对数据集进行排序
roster <- roster[order(lastname,firstname),]

roster # 排序后的roster
firstname lastname math science english score grade
6 Cheryl Cushing 512 85 28 0.35 C
1 John Davis 502 95 25 0.56 B
9 Joel England 573 89 27 0.70 B
4 David Jones 358 82 15 -1.16 F
8 Greg Knox 625 95 30 1.34 A
5 Janice Markhammer 495 75 20 -0.63 D
3 Bullwinkle Moose 412 80 18 -0.86 D
10 Mary Rayburn 522 86 18 -0.18 C
2 Angela Williams 600 99 22 0.92 A
7 Reuven Ytzrhak 410 80 15 -1.05 F

END

猜你喜欢

转载自blog.csdn.net/jayqilixiang/article/details/85050849