第5章工欲善其事、必先利其器
代码,是延伸我们思想最好的工具。
第6章基础编程——用别人的包和函数讲述自己的故事
6.1编程环境
1.R语言的三段论
大前提:计算机语言程序=算法+数据结构
小前提:R语言不过是计算机语言的一种
结论:R语言约等于基础编程+数据对象
2.运行机制
RStudio=记事本+R Console
6.2Mini案例
学生文理分科小案例(还有问题)
R仅有的命令形式是返回结果的函数和表达式
赋值是一种常见的操作:对象的读取、转换、模型的建立等
赋值给新的对象,往往也意味着数据的流转:读取、转换、探索、建模、评估等操作。
6.3站在巨人的肩膀上
1.编程的法则:
R编程=用别人的包和函数讲述自己的故事
2.如何搜索包
①上百度
②逛论坛,找答案,[r]搜索
https://stackoverflow.com/questions/tagged/r
③sos,扩展包,安装sos包,利用findFn()函数搜索包
④Task Views
⑤专注于某个领域,慢慢积累
3.利用好帮助文档,如?c
6.4控制流
结构化编程:任何简单或者复杂的逻辑都可以由顺序、分支和循环这三种基本结构组合而成。
1.顺序结构
> yw <- c(94,87,92,91,85,92)
> sx <- c(82,94,79,84,92,82)
> wy <- c(96,89,86,96,82,85)
> ysw <- yw+sx+wy
> ysw
[1] 272 270 257 271 259 259
> (yw <- yw+2)
> (mean_score <- mean(yw))#求语文平均分
[1] 92.16667
> sd(yw)#求语文成绩标准差
[1] 3.430258
> c(sd(yw),sd(sx),sd(wy))
[1] 3.430258 6.058052 5.865151
> show(yw)
[1] 96 89 94 93 87 94
> show(sx)#显示数学成绩
[1] 82 94 79 84 92 82
> yw >= 90#向量化操作:逻辑判断
[1] TRUE FALSE TRUE TRUE FALSE TRUE
> yw >= 85&sx >=85#向量化操作:逻辑判断
[1] FALSE TRUE FALSE FALSE TRUE FALSE
> yw >=95 | sx >=95#向量化操作:逻辑判断
[1] TRUE FALSE FALSE FALSE FALSE FALSE
2.分支结构
条件表达式根据条件而执行不同的代码
if(条件){
cons.expr
}else{
alt.expr
}
注意:条件为一个标量的真或者假值,else子句如果存在的话,必须和}在同一行。else不能单起一行
> min_score <- min(yw)#语文最低成绩为87
if(min_score>=90){
message("语文成绩全部为优") //控制台输出
}else if(min_score>=80){
message("语文成绩至少为良")
}else{
message("并非所有同学语文成绩均为优良")
}
> ifelse(yw >= 90,"优",ifelse(yw >= 88,"较好","一般"))
[1] "优" "较好" "优" "优" "一般" "优"
3.循环结构 for while repeat
两种语句用于控制循环:
break 语句可以从当前运行的循环里面跳出来
next 语句会导致控制立即返回到循环的起点,next后面的语句不会被执行
实例:斐波那契数列
n_fib <- 16
fib <- numeric(n_fib)
fib[1:2] <- c(1,1)
for(i in 3:n_fib){
fib[i] <- fib[i-1]+fib[i-2]
show(fib[i])
}
fib
> fib
[1] 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
求1000以内的斐波那契数列:
#不知道循环多少次,仅知道终止条件,通过while来实现
fib <- c(1,1)
while(sum(tail(fib,2))<1000){
fib <- c(fib,sum(tail(fib,2)))
}
fib
#也可以通过repeat来无条件循环,直到满足某个条件时break
fib <- c(1,1)
repeat{ //repeat==while(T)
if(sum(tail(fib,2))>=1000){
break
}
fib <- c(fib,sum(tail(fib,2)))
}
fib
另一个例子:抽取幸运数字52
time_count <- 0
repeat{
my_number <- sample(100,1)#从1到100里面抽取一个数字
time_count <- time_count+1
if(my_number==52){
message("Hahaha,I finally got '52' after",time_count,"times")
break
}else {
message(time_count,":Not lucky enough [",my_number, "]")
}
}
4.再说向量化:尽量不要使用显式循环,能向量化的运算的,尽量向量化,运算时间大大减少。
只要串行模式不是必须的,采用并行的方式。
R里面的并行作业:
向量化函数:sqrt(),sin(),round(),as.numeric(),cut(),weekdays(),+,-,*,/,&,|,%in%.....
6.5函数(1)
事不过三
1.编写函数
}
ps:R里面一切都是对象,对象通过赋值来产生,函数也不例外。
函数声明关键字是function,function返回值就是函数
参数列表是以逗号分隔,函数主体可以是任何合法的R表达式
若无return语句,最后一个表达式的值作为返回值
以function_name(arg1,arg2,....)的形式调用函数
#摄氏度到华氏度的转换
ce2fa <- function(ce){#参数ce为输入
fa <- 1.8*ce+32#对输入进行处理
return(fa)#输出相应的值
}
ce2fa(0)#0摄氏度相当于32华氏度
[1] 32
ce2fa(0:10)
[1] 32.0 33.8 35.6 37.4 39.2 41.0 42.8 44.6 46.4 48.2 50.0
#注意位置参数和名义参数
frm <- function(name,frm="BUPT"){
cat(name,"is frm",frm) //显示
}
frm("axb")
axb is frm BUPT
frm("axb","BJTU") //位置参数
axb is frm BJTU
frm(frm="BJTU",name="axb")//名义参数
axb is frm BJTU
2.熟而不觉的函数:作为函数的二元操作符
+,-,*,/其实都是函数
%in%运算符:左侧的每个元素是否在右侧的集合之中
c(1,3,9) %in% 1:3
'%in%'(c(1,3,9),1:3)
[1] TRUE TRUE FALSE
#自己定义二元操作符函数:a,b为直角边,c为斜边
"%ab2c" <- function(a,b){
sqrt(sum(a^2,b^2))
}
"%ab2c%"(3,4)
#看完%ab2c%之后,对下面的符号,也就觉得不过如此了
library(purrr)
x <- c(17,28,17,12,15,12,49)
x %>%
unique() %>% #管道操作符也是一个二元操作符,函数而已
sort()
[1] 12 15 17 28 49
#等价于下面的代码,不过是更加简洁优雅
x <- c(17,28,17,12,15,12,49)
x2 <- unique(x) #剔除重复的数目
x3 <- sort(x2)
x3
[1] 12 15 17 28 49
#定义二元操作符的时候,必须用双引号括起来
5+2
"+" <- function(x,y){
x*y
}
5 + 2
[1] 10
rm("+")#消除恶作剧的+运算
5+2
[1] 7
ps:特殊函数的帮助文档
?“+” #双引号
?‘+’#单引号
?·+·#反单引号
6.6函数(2)
1.不一样的plot
x <- seq(1,100,by=10)
y <- 2*x+10
xy <- cbind(x,y)
class(xy) #矩阵
[1] "matrix" "array"
plot(xy,
xlim = c(1,100),
ylim = c(0,230),
type = "o",col = "red"
)
x <- seq(1,100,by=10)
y <- 2*x+10
my_model <- lm(y~x) #拟合一个线性模型
class(my_model) #线性模型
[1] "lm"
op <- par(mfrow=c(1,1))
plot(my_model)
par(op)
多态的问题:针对不同的对象有不同的行为,泛型函数
2.泛型函数:见什么人说什么话,到什么山上唱什么歌
定义和调用的过程
#编写泛型函数
interface <- function(x,y){ #接口函数
message("Singal interface")
UseMethod("particular",y)#参照第二个参数的类别来进行分发
}
particular.classA <- function(x,y){#分发函数
message("Different behavior:classA")
}
particular.classB <- function(x,y){#分发函数
message("Different behavior:classB")
}
particular.default <- function(x,y){#分发函数
message("Different behavior:default")
}
x <- 1:10
y <- 1:20
class(y) <- "classA"#给A贴上标签-classA
interface(x,y)
Singal interface
Different behavior:classA
类标签不一样的时候,接口是一样的
class(y) <- NULL
interface(x,y)
Singal interface
Different behavior:default
重新审视+:
> methods("+")
[1] +.Date +.glue* +.POSIXt +.vctrs_vctr*
see '?methods' for accessing help and source code
> library(ggplot2)
> methods("+")
[1] +.Date +.gg* +.glue* +.POSIXt
[5] +.vctrs_vctr*
see '?methods' for accessing help and source code
定义自己的+
"+.onlyFirst" <- function(a,b){
return(a[1]+b[1])
}
a <- 1:5
a+6:10
1] 7 9 11 13 15
class(a) <- "onlyFirst"#给a贴上一个类标签onlyFirst
a+6:10
[1] 7
3.递归:层层递进,逐层回归
老和尚讲故事:
rep(x, …):将vector x的值循环n遍
old_monk_story <- function(depth=1){
message(rep(" ",depth),"400 years ago(",2020-400*depth,"),monk[",depth,"]is
telling the story:")
if(2020-400*(depth+1)>=66){#据说佛教公元66年传入中国
old_monk_story(depth+1)
}
message(rep(" ",depth),"monk [",depth,"]finshed his story")
}
old_monk_story()
400 years ago(1620),monk[1]is
telling the story:
400 years ago(1220),monk[2]is
telling the story:
400 years ago(820),monk[3]is
telling the story:
400 years ago(420),monk[4]is
telling the story:
monk [4]finshed his story
monk [3]finshed his story
monk [2]finshed his story
monk [1]finshed his story
重新审视斐波那契数列
fib <- function(n){
if(n==1){
return(1)
}else{
return(c(fib(n-1),sum(tail(fib(n-1),n=2))))
}
}
fib(10)
[1] 1 1 2 3 5 8 13 21 34 55
错题整理:
1.对于特殊的函数if或者+等,通过helo()或是单引号、双引号、反单引号查找帮助文档
2.repeat循环体中必然有一条break语句,next语句只是中断本轮循环跳转至下一轮循环。若repeat语句中仅有next而无break,依然是死循环。
第7章数据对象——面向数据对象学习R语言
7.1向量与因子(1)
1.数据对象:
向量/因子
矩阵/数组
列表/数据框
2.创建向量
#创建向量最常见的方式c(),combine
#字符型向量
xm <- c("周","xie","gao")
Xb <- c("女","男","男")
#数值型向量
yw <- c(94,92,98)
#逻辑型向量
xb2 <- c(R,T,F)
#不能有混合类型
my_pi <- c(3,".",1,4,1,5,9,2,6)
my_pi
[1] "3" "." "1" "4" "1" "5" "9" "2" "6"
#材质不一样时强制转换
my_pi <- c(3,T,4,T,5,9,2,6)
my_pi
[1] 3 1 4 1 5 9 2 6
c(1,2,c(4,3),c(1,0))#不存在包含向量的向量,一律拆包
[1] 1 2 4 3 1 0
c(1,2,4,3,1,0
[1] 1 2 4 3 1 0
> (x1 <- vector("numeric",8))#事先知道长度和类型 ,默认值是0
[1] 0 0 0 0 0 0 0 0
> (x2 <- numeric(8))
[1] 0 0 0 0 0 0 0 0
> (x3 <- character(8))
[1] "" "" "" "" "" "" "" ""
> (x4 <- vector(len=8))
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
> (x5 <- logical(8))
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
> #规则数列
> #等差数列
> seq(from=1,to=10,by=2)
[1] 1 3 5 7 9
> seq(from=20,to=1,by=-2)
[1] 20 18 16 14 12 10 8 6 4 2
> seq(from=1,to=20,length=10)#10个数,10个端点
[1] 1.000000 3.111111 5.222222 7.333333 9.444444 11.555556
[7] 13.666667 15.777778 17.888889 20.000000
> 1:10#创建from:10,步长为1的等差数列
[1] 1 2 3 4 5 6 7 8 9 10
> pi:1
[1] 3.141593 2.141593 1.141593
> #注意运算符的优先级
> 1:10-1#长度为10,:的优先级比-高
[1] 0 1 2 3 4 5 6 7 8 9
> 1:(10-1)#长度为9
[1] 1 2 3 4 5 6 7 8 9
> #不要有记忆的负担,在R里,不要吝啬()和{}的使用
创建向量:随机数列
> #产生随机数
> sample(10)#随机抽样
[1] 9 3 8 1 5 2 10 4 7 6
> sample(c("b","u","p","t","a","x","b"))#随机抽样
[1] "t" "a" "u" "b" "p" "x" "b"
> set.seed(2012)#设定随机数种子,设定随机数结果固定的
> sample(10)#结果应该是一致的,reproduction research
[1] 4 8 6 2 3 1 9 7 10 5
> (train_idx <- sample(1:10,7))
[1] 3 5 6 10 1 7 2
> #有放回的抽样
> re_sample <- sample(1:100,100,replace = T)
> unique_re_sample <- unique(re_sample) #去掉重复的
> length(unique_re_sample)#有放回的抽样,有约36.8%的数不被抽
[1] 63
3.访问向量的子集,向量的下标,向量的子集通过[]来指定
第一种方法:采用1~n的正整数来指定,n为向量的长度
> yw <- c(94,87,92,91,85,92)
> yw[c(2,5)]
[1] 87 85
> yw[c(2,5)]-90
[1] -3 -5
> yw[c(2,5)] <- yw[c(2,5)]+6
> yw
[1] 94 93 92 91 91 92
> yw[] <- mean(yw)#每一个元素都被赋值
> yw
[1] 92.16667
> yw <- mean(yw)
> yw
[1] 92.16667
>
> xm <- c("zhou","tang","xie","gao")
> xm[c(1,3,3,2)]
[1] "zhou" "xie" "xie" "tang"
子集不子,下标可重复,顺序可变
方法二:采用负整数,反向选出某些元素
> yw <- c(94,87,92,91,85,92)
> yw[-c(2,5)]
[1] 94 92 91 92
> which(yw<90) //输出的是下标
[1] 2 5
> idx <- which(yw<90)
> yw[-idx]#避免了硬代码(可变的),增强了代码的可维护性
[1] 94 92 91 92
方法三:逻辑下标
> xm <- c("zhou","tang","shu","weng","qi","zhan")
> yw <- c(94,87,92,91,85,92)
> yw<90
[1] FALSE TRUE FALSE FALSE TRUE FALSE
> yw[yw<90]
[1] 87 85
> xm[yw<90]
[1] "tang" "qi"
R为何智能的识别出了语文成绩小于90分(yw<90)的同学呢?
方法四:通过元素名称访问相应的子集
> xm <- c("zhou","tang","shu","weng","qi","zhan")
> yw <- c(94,87,92,91,85,92)
> names(yw) <- xm #取名
> yw
zhou tang shu weng qi zhan
94 87 92 91 85 92
> yw[c("tang","qi")]
tang qi
87 85
4.向量的基本操作
向量排序:
#向量排序 数值向量,默认从低到高,若想从高到低的话
fen_shu_xian2016 <- c(中科大=671,中央民族大学=625,北大=678,人大=670,
清华=680,北交=640,北京科技大=635,北京化工大=620,北邮=646,中农=634,北林=621)
sort(fen_shu_xian2016)
北京化工大 北林 中央民族大学 中农 北京科技大
620 621 625 634 635
北交 北邮 人大 中科大 北大
640 646 670 671 678
清华
680
order(fen_shu_xian2016,decreasing = T) #返回的是下标
[1] 5 3 1 4 9 6 7 10 2 11 8
> fen_shu_xian2016[order(fen_shu_xian2016,decreasing = T)]#把下标交给
清华 北大 中科大 人大 北邮
680 678 671 670 646
北交 北京科技大 中农 中央民族大学 北林
640 635 634 625 621
北京化工大
620
向量逆序排序:
> yw <- c(94,87,92,91,85,92)
> rev(yw)
[1] 92 85 91 92 87 94
> yw[6]#可以用来取最后一个元素,但是这种硬代码很难维护
[1] 92
> yw[length(yw)]#基本可行的方法
[1] 92
> tail(yw,n=1)#更好的选择,推荐
[1] 92
> rev(tail(yw,n=3))#等价于head(rev(yw),n=3)
[1] 92 85 91
数值向量运算:(从数学角度来看)
#原点
p0 <- c(x=0,y=0)
#向量1
p1 <- c(x=1,y=2)
#向量2
p2 <- c(x=2,y=3)
#求和
p3 <- p1+p2
#数乘
p4 <- 1.5*p3
#内积:表示同心同向性
sum(p1*p2)
> #向量的内积
> set.seed(2012)#括号内数值任意即可
> x <- rnorm(100)#生成随机数的数列,服从正太分布
> y <- rnorm(100)
> #求向量的内积
> sum(x*y)
[1] -11.1336
> sum(sort(x),sort(y))
[1] -20.56163
> sum(sort(x),sort(y,decreasing = T))
[1] -20.56163
7.2向量与因子(2)
1.变量分类
前两种无序因子和有序因子可以用因子来存储;
2.向量与因子的区别和联系:
向量用于存储数值变量(定距定比),因子用于存储类别变量(定类定序)
作为类别变量,只有有限个取值(类别),称为水平levels,取值水平往往远远少于观测对象(记录)的个数
在分组统计中,因子常用来作分组变量;分类问题均要求因变量为因子;在其他一些算法建模过程中,也要求其变量为因子(如arules::apriori())
因子也是也是更有效的存储方式:存储为整型向量,只不过每一个1~levels的正整数代表了相应的类别
3.因子的创建
方法一:基于向量
> xb <- c("女","男","男","女","男","女")
> xb
[1] "女" "男" "男" "女" "男" "女"
> typeof(xb)
[1] "character"
> xb <- factor(xb)
> xb <- factor(xb)
> xb
[1] 女 男 男 女 男 女
Levels: 男 女因子的基本操作
> xb[-c(2:3,6)]
[1] 女 女 男
Levels: 男 女
> xb[1] <- "男"
> xb
[1] 男 男 男 女 男 女
Levels: 男 女
> xb=="男"
[1] TRUE TRUE TRUE FALSE TRUE FALSE
> nlevels(xb)#取值水平的个数
[1] 2
> levels(xb)#取值水平
[1] "男" "女"
> typeof(xb)
[1] "integer"#内部实际存储为一个整型的向量
> as.numeric(xb)
[1] 1 1 1 2 1 2
> as.character(xb)
[1] "男" "男" "男" "女" "男" "女"
对于因子而言,表面上看是字符,实际上在内存里面是一个整型的向量。
> number_factors <- factor(c(10,20,20,20,10))
> mean(number_factors)
[1] NA
表面上看只是字符
> as.numeric(number_factors)#使用数值向量进行创建的时候,“10”当成字符来看待
[1] 1 2 2 2 1
> mean(as.numeric(number_factors))
[1] 1.6
> mean(as.numeric(as.character(number_factors)))
[1] 16
> mean(as.numeric(levels(number_factors)[number_factors]))
[1] 16
> #有序因子
> score <- factor(c("优","良","优","优","良","优"),ordered = T)
> score[1]>score[2]#怎么识别出来的呢?
[1] TRUE
> days <- factor(c("周一","周三","周二","周二"),ordered = T)
> days[3]<days[2]
[1] TRUE
> days[1]<days[2]
[1] FALSE
> days
[1] 周一 周三 周二 周二
Levels: 周二 < 周三 < 周一 #其实并没有那么智能,只是内部编码问题而已,按照字母顺序
#规定好levels,给定顺序
> days <- factor(c("周一","周三","周二","周二"),ordered = T,levels = c("周一","周二","周三"))
> days
[1] 周一 周三 周二 周二
Levels: 周一 < 周二 < 周三
> days[1]<days[3]
[1] TRUE
方法二:基于数值变量使用cut()进行分箱,进行离散化处理。
> #实战才是王道:数据分箱
> #百分制成绩变为五分制成绩
> yw <- c(94,87,92,91,85,92)
> #数据分箱
> yw5 <- cut(yw,breaks=c(0,(6:10)*10))#挖坑的过程,后面0,60,70,80,90,100这几个端点
> yw5
[1] (90,100] (80,90] (90,100] (90,100] (80,90] (90,100]
Levels: (0,60] (60,70] (70,80] (80,90] (90,100] #左开右闭,0没有取到
改进:
> #数据分箱+闭区间
> yw5 <- cut(yw,breaks=c(0,(6:10)*10),include.lowest = T)#挖坑的过程,后面0,60,70,80,90,100这几个端点
> yw5
[1] (90,100] (80,90] (90,100] (90,100] (80,90] (90,100]
Levels: [0,60] (60,70] (70,80] (80,90] (90,100]
问题:60划分区间不对
> #数据分箱+闭区间+左闭右开
> yw5 <- cut(yw,breaks=c(0,(6:10)*10),include.lowest = T,right=F)
> yw5
[1] [90,100] [80,90) [90,100] [90,100] [80,90) [90,100]
Levels: [0,60) [60,70) [70,80) [80,90) [90,100]
进一步改进:
> #数据分箱+闭区间+左闭右开+有序因子
> yw5 <- cut(yw,breaks=c(0,(6:10)*10),include.lowest = T,right=F,ordered_result = T)
> yw5
[1] [90,100] [80,90) [90,100] [90,100] [80,90) [90,100]
Levels: [0,60) < [60,70) < [70,80) < [80,90) < [90,100]
> #数据分箱+闭区间+左闭右开+有序因子+标签
> yw5 <- cut(yw,breaks=c(0,(6:10)*10),include.lowest = T,right=F,ordered_result = T,
+ labels = c("不及格","及格","中","良","优"))
> yw5
[1] 优 良 优 优 良 优
Levels: 不及格 < 及格 < 中 < 良 < 优
7.3矩阵与数组(1)
1.矩阵的创建:
#单变量观测值可以用向量或因子存储
#假设对观测对象的多个属性同时进行记录(多变量)
#若这些向量是同质的,宜采用矩阵作为一个整体进行存储
#依然以学生成绩这份数据为例
xm <- c("周莉","唐海明","舒江辉","翁可","奇强","詹蓉")
yw <- c(94,87,92,91,85,92)
sx <- c(82,94,79,84,92,82)
wy <- c(96,89,86,96,82,85)
#语文、数学、外语三科成绩作为一个整体
ysw <- matrix(c(94,87,92,91,85,92,
82,94,79,84,92,82,
96,89,86,96,82,85),ncol = 3)#分成3列,长度为18的数值向量
#矩阵在创建的时候案列优先进行填充
colnames(ysw) <- c("yw","sx","wy")
row.names(ysw) <- xm#给行或者列命名
View(ysw)
#假设数据本身就是站着的
ysw <- matrix(
c(94,82,96,
87,94,89,
92,79,86,
91,84,96,
85,92,82,
92,82,85),
byrow = TRUE,#注意byrow=参数的设置,默认是F
ncol = 3)
colnames(ysw) <- c("yw","sx","wy")
row.names(ysw) <- xm
View(ysw)
矩阵的基本性质:
> colnames(ysw)
[1] "yw" "sx" "wy"
> row.names(ysw)
[1] "周莉" "唐海明" "舒江辉" "翁可" "奇强" "詹蓉"
> nrow(ysw)#行数
[1] 6
> ncol(ysw)#列数
[1] 3
> dim(ysw)#行数和列数
[1] 6 3
> dimnames(ysw)#行列名称
[[1]]
[1] "周莉" "唐海明" "舒江辉" "翁可" "奇强" "詹蓉"
[[2]]
[1] "yw" "sx" "wy"
#子集的访问仍然是通过[]
#由于矩阵是二维的,需要','来分别指定行和列
ysw[1,]#第一个同学语文、数学、外语得分
ysw["周莉",]#同上
yw sx wy
94 82 96
ysw[,1]#语文成绩
ysw[,"yw"]#同上
周莉 唐海明 舒江辉 翁可 奇强 詹蓉
94 87 92 91 85 92
> ysw["周莉",2:3]
sx wy
82 96
> ysw[1,c("sx","wy")]
sx wy
82 96
> ysw[1,-1]
sx wy
82 96
行列重排:
> #列重新排序
> ysw[,c("sx","yw","wy")]
sx yw wy
周莉 82 94 96
唐海明 94 87 89
舒江辉 79 92 86
翁可 84 91 96
奇强 92 85 82
詹蓉 82 92 85
> ysw[,c(2,1,3)]
sx yw wy
周莉 82 94 96
唐海明 94 87 89
舒江辉 79 92 86
翁可 84 91 96
奇强 92 85 82
詹蓉 82 92 85
> #行进行排序:按照数学成绩进行排序
> (order_sx <- order(ysw[,"sx"],decreasing = T))
[1] 2 5 4 1 6 3
> ysw[order_sx,]
yw sx wy
唐海明 87 94 89
奇强 85 92 82
翁可 91 84 96
周莉 94 82 96
詹蓉 92 82 85
舒江辉 92 79 86
#矩阵合并
#观测到新的记录
ysw1 <- matrix(c(94,87,92,91,85,92,
82,94,79,84,92,82,
96,89,86,96,82,85),ncol = 3,
dimnames = list(
c("周莉","唐海明","舒江辉","翁可","奇强","詹蓉"),
c("yw","sx","wy")
))
ysw2 <- matrix(
c(88,81,72,89,86,87),
ncol = 3,
dimnames = list(
c("穆伶俐","易伟杰"),
c("yw","sx","wy")
)
)
#叠罗汉一样
ysw <- rbind(ysw1,ysw2)
View(ysw)
#新增列
zzls <- matrix(
c(97,97,
95,94,
98,95,
93,97,
93,87,
91,90,
94,87,
97,94),
ncol = 2,byrow = T,
dimnames = list(
c("周莉","唐海明","舒江辉","翁可","奇强","詹蓉","穆伶俐","易伟杰"),
c("zz","ls")
)
)
cjb <- cbind(ysw,zzls)#按列进行合并
View(cjb)
其他一些基本操作:
> rowSums(cjb)#每个同学的总成绩
周莉 唐海明 舒江辉 翁可 奇强 詹蓉 穆伶俐 易伟杰
466 459 450 461 439 440 427 448
> colMeans(cjb)#按列求平均值,每门课的平均分
yw sx wy zz ls
88.750 84.250 88.375 94.750 92.625
> #更一般的方法
> apply(cjb,1,sum)#第二个参数表示作用的要么是行,要么是列
周莉 唐海明 舒江辉 翁可 奇强 詹蓉 穆伶俐 易伟杰
466 459 450 461 439 440 427 448
> apply(cjb,2,mean)
yw sx wy zz ls
88.750 84.250 88.375 94.750 92.625
> round(apply(cjb,2,sd),digits = 2)#sd标准差
yw sx wy zz ls
4.33 7.23 5.10 2.43 4.10
> #可以自定义函数
> coefficient_of_variation <- function(x){
+ sd(x)/mean(x)
+
+ }
> apply(cjb,2,coefficient_of_variation)
yw sx wy zz ls
0.04883661 0.08576790 0.05767772 0.02569779 0.04430305
> #当然,也可以采用匿名函数
> apply(cjb, 2, function(x){
+ sd(x)/mean(x)
+ })
yw sx wy zz ls
0.04883661 0.08576790 0.05767772 0.02569779 0.04430305
总结:apply代表了一种数据处理模式
split-apply-combine模式,先分组,然后对每一个组进行操作,然后将操作结果进行combine在一起
apply函数族,以及tidyverse包
7.4矩阵和数组(2)
1.矩阵的运算,可以通过solve(A,b)
解以下方程组:
#定义系数矩阵
A <- matrix(
c(1,2,3,
2,2,5,
3,5,1),
ncol = 3,
byrow = T#按行排列
)
b <- 1:3
solve(A,b)
[1] 1 0 0
> #可以利用solve函数求逆矩阵
> diag(3)#生成单位矩阵
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 1 0
[3,] 0 0 1
> solve(A,diag(3))
[,1] [,2] [,3]
[1,] -1.5333333 0.86666667 0.26666667
[2,] 0.8666667 -0.53333333 0.06666667
[3,] 0.2666667 0.06666667 -0.13333333
> solve(A)#默认b是单位矩阵
[,1] [,2] [,3]
[1,] -1.5333333 0.86666667 0.26666667
[2,] 0.8666667 -0.53333333 0.06666667
[3,] 0.2666667 0.06666667 -0.13333333
> solve(A) %*% A #A的逆乘以A
[,1] [,2] [,3]
[1,] 1.000000e+00 8.881784e-16 1.054712e-15
[2,] -4.440892e-16 1.000000e+00 -7.077672e-16
[3,] -5.551115e-17 -1.110223e-16 1.000000e+00
> sqrt(2)^2==2
[1] FALSE
#以上两个例子原因都是一样的,涉及到R存储的有限位数,根号2是一个无理数,有无限位,但在存储的时候只能存储一部分,所以并不是完全等于2
> dplyr::near(sqrt(2)^2,2)#dplyer是一个包
[1] TRUE
> all(dplyr::near(solve(A) %*% A,diag(3)))
[1] TRUE
2.数组
数组是矩阵的扩展,矩阵是二位数组,以图像处理为例,简述三维数组的操作。
#数组
#读入一个彩色jpg文件,在R里面就是一个数组
> jpg_url <- "https://raw.githubusercontent.com/byaxb/RDataAnalytics/master/data/presidents.jpg"
> download.file(jpg_url,"presidents.jpg",mode = "wb")
试开URL’https://raw.githubusercontent.com/byaxb/RDataAnalytics/master/data/presidents.jpg'
Error in download.file(jpg_url, "presidents.jpg", mode = "wb") :
无法打开URL'https://raw.githubusercontent.com/byaxb/RDataAnalytics/master/data/presidents.jpg'
此外: Warning message:
In download.file(jpg_url, "presidents.jpg", mode = "wb") :
InternetOpenUrl失败:’无法与服务器建立连接'
> library(imager)
载入需要的程辑包:magrittr
载入程辑包:‘imager’
The following object is masked from ‘package:magrittr’:
add
The following objects are masked from ‘package:stats’:
convolve, spectrum
The following object is masked from ‘package:graphics’:
frame
The following object is masked from ‘package:base’:
save.image
> presidents <- load.image("presidents.jpg")
Error in wrap.url(file, load.image.internal) : File not found
> str(presidents)
'cimg' num [1:482, 1:345, 1, 1:3] 0.984 0.961 0.918 0.902 0.902 ...#z轴3个二维数组
#图像与数组,将第2,3个图层赋值为0
presidents[,,2] <- 0
presidents[,,3] <- 0
plot(presidents)
#只看绿色图层
presidents[,,1] <- 0
presidents[,,3] <- 0
plot(presidents)
#调色,都是对数组的操作
#黄色
presidents[,,3] <- 0
plot(presidents)
#加上马赛克,加一个噪声模糊处理
area_coor_x <- 350:449#100
area_coor_y <- 110:259#150
array_dim <- c(length(area_coor_x),length(area_coor_y),3)
array_data <- runif(prod(array_dim))#prod()表示相乘生成噪声,runif()表示均匀分布
randow_noise <- array(dim = array_dim,data = array_data)
presidents[area_coor_x,area_coor_y,] <- (1-0.6)*presidents[area_coor_x,area_coor_y,]+
0.6*randow_noise
plot(presidents)
7.5列表与数据框(1)
定义:列表是对象的有序集合,包含的对象又称为它的分量
列表是最为灵活,最具有包容性
对所包含的对象没有限制,可以是不同的类型、不同的长度
> #北京邮电大学下设以下学院
> xue_yuan <- c("信息与通信学院","电子工程学院","计算机学院","自动化学院","软件学院","数字媒体与设计艺术学院","现代邮政学院","网络空间安全学院","光电信息学院","理学院","经济管理学院",
+ "马克思主义学院","国际学院","网络教育学院","继续教育学院","民族教育学院")
> #拥有以下基地
> ji_di <- c(国家重点实验室=2,国家工程实验室=2,部级实验室=9)
> xiao_qu <- c("西土城路校区","沙河校区","宏福校区")#校区分布
> xue_sheng <- c(全日制=30000,非全日制=4500)#学生数量
> #变成一个整体,集合在一起
> bupt <- list(xue_yuan=xue_yuan,
+ xiao_qu=xiao_qu,
+ ji_di=ji_di,
+ xue_sheng=xue_sheng)
> #查看一些属性
> length(bupt)
[1] 4
> names(bupt)
[1] "xue_yuan" "xiao_qu" "ji_di" "xue_sheng"
> typeof(bupt)
[1] "list"
一些基本操作
> #访问列表子集¥
> bupt$xue_sheng
全日制 非全日制
30000 4500
> bupt$xue_sheng["全日制"]
全日制
30000
> sum(bupt$xue_sheng)
[1] 34500
> #通过[]来访问子集
> bupt[4]#提取的还是列表的形式
$xue_sheng
全日制 非全日制
30000 4500
> typeof(bupt[4])#单个[]看到的依然是包装箱
[1] "list"
> bupt[[4]] #双层[]才进入包装箱内部,看到组成部分
全日制 非全日制
30000 4500
> typeof(bupt[[4]])
[1] "double"
> sum(bupt[4])
Error in sum(bupt[4]) : 'type'(list)参数不对
> sum(bupt[[4]])#正确的打开方式
[1] 34500
> bupt["xue_sheng"]
$xue_sheng
全日制 非全日制
30000 4500
————————————————————————————————————————————————————————————————————————————————————
> bupt[["bupt"]]
NULL
> sum(bupt[4])
Error in sum(bupt[4]) : 'type'(list)参数不对
> sum(bupt[[4]])#正确的打开方式
[1] 34500
> bupt["xue_sheng"]
$xue_sheng
全日制 非全日制
30000 4500
> bupt[["xue_sheng"]]
全日制 非全日制
30000 4500
总结:一下三种方式效果相同
bupt$xue_sheng
bupt[[4]]
bupt[["xue_sheng"]]
全日制 非全日制
30000 4500
增、删、改、查
> #增加一类,直接赋值
> bupt$A_xueke <- c("信息与通信工程","计算机科学与技术","电子科学与技术")
> length(bupt)
[1] 5
> names(bupt)
[1] "xue_yuan" "xiao_qu" "ji_di" "xue_sheng" "A_xueke"
> bupt$A_xueke <- NULL#注意NULL/NA/""的区别
> names(bupt)
[1] "xue_yuan" "xiao_qu" "ji_di" "xue_sheng"
列表操作:
#队列表的每一个组成部分,执行某种操作
> (component_length <- lapply(bupt, length))
$xue_yuan
[1] 16
$xiao_qu
[1] 3
$ji_di
[1] 3
$xue_sheng
[1] 2
> unlist(component_length)#拉平,变成带名称的数值向量
xue_yuan xiao_qu ji_di xue_sheng
16 3 3 2
> sapply(bupt,length)
xue_yuan xiao_qu ji_di xue_sheng
16 3 3 2
> sapply(bupt,typeof)
xue_yuan xiao_qu ji_di xue_sheng
"character" "character" "double" "double"
7.6列表和数据框(2)
1.数据整理最后都是为了得到数据框
2.数据框的组成:
数据框是最美好的数据对象
形式上是矩阵,本质上是列表
与数据库关系表、Excel中的sheet相似
个体-变量矩阵
列:变量、属性、特征、维度
行:记录、观测值、n维数据空间的一个点
3.创建数据框
xm <- c("周莉","唐海明","舒江辉","翁可","奇强","詹蓉")
xb <- factor(c("女","男","男","女","男","女"))
yw <- c(94,87,92,91,85,92)
sx <- c(82,94,79,84,92,82)
wy <- c(96,89,86,96,82,85)
cjb <- data.frame(xm=xm,#非同质,和列表类似
xb=xb,
yw=yw,
sx=sx,
wy=wy)
cjb
xm xb yw sx wy
1 周莉 女 94 82 96
2 唐海明 男 87 94 89
3 舒江辉 男 92 79 86
4 翁可 女 91 84 96
5 奇强 男 85 92 82
6 詹蓉 女 92 82 85
4.数据框的基本操作
#由于数据框本质上是列表,可以通过以下三种方式访问其中的列
cjb$xm
cjb[[1]]
cjb[["xm"]]
[1] "周莉" "唐海明" "舒江辉" "翁可" "奇强" "詹蓉"
#一般来说[[]]的用法较少,要么采用$,要么采用以下的矩阵式操作,逗号前面是行,后面是列
cjb[,1]
cjb[,"xm"]
> cjb[1,]
xm xb yw sx wy
1 周莉 女 94 82 96
> cjb[c(1,3),c("xm","sx")]
xm sx
1 周莉 82
3 舒江辉 79
> cjb[1:3,-1]
xb yw sx wy
1 女 94 82 96
2 男 87 94 89
3 男 92 79 86
#作为列表,通过美元符号增加一列政治zz
cjb$zz <- c(97,95,98,93,93,91)
#像矩阵,cbind也可以
cjb <- cbind(cjb,ls=c(97,94,95,97,87,90))
View(cjb)
5.读取数据
#数据不会再代码里逐字敲入,也不会通过控制台输入
#而是直接读取已经采集好的数据
cjb_url <- "https://github.com/byaxb/RDataAnalytics/raw/master/data/cjb.csv"
cjb <- read.csv(cjb_url,header = T,stringsAsFactors = F)
View(cjb)
head(cjb)#默认显示前6行
tail(cjb,n=3)#默认后6行
> #查看数据的结构
> #Compactly Display the Structure
> str(cjb)
'data.frame':775 obs. of 13 variables:
$ xm : chr "周黎" "汤海明" "舒江辉" "翁柯" ...
$ bj : int 1101 1101 1101 1101 1101 1101 1101 1101 1101 1101 ...
$ xb : chr "女" "男" "男" "女" ...
$ yw : int 94 87 92 91 85 92 88 81 88 94 ...
$ sx : int 82 94 79 84 92 82 72 89 77 81 ...
$ wy : int 96 89 86 96 82 85 86 87 95 88 ...
$ zz : int 97 95 98 93 93 91 94 97 94 91 ...
$ ls : int 97 94 95 97 87 90 87 94 84 85 ...
$ dl : int 98 94 96 94 88 92 88 96 94 98 ...
$ wl : int 95 90 89 82 95 82 89 81 87 81 ...
$ hx : int 94 90 94 90 94 98 98 88 94 88 ...
$ sw : int 88 89 87 83 93 90 94 83 82 88 ...
$ wlfk: chr "文科" "文科" "文科" "文科" ...
> summary(cjb)#对数据进行统计描述
xm bj xb yw sx
Length:775 Min. :1101 Length:775 Min. : 0.00 Min. : 0.00
Class :character 1st Qu.:1104 Class :character 1st Qu.:85.00 1st Qu.: 81.00
Mode :character Median :1107 Mode :character Median :88.00 Median : 89.00
Mean :1108 Mean :87.27 Mean : 86.08
3rd Qu.:1111 3rd Qu.:91.00 3rd Qu.: 95.00
Max. :1115 Max. :96.00 Max. :100.00
wy zz ls dl wl
Min. : 0.0 Min. : 0.00 Min. : 0.00 Min. : 0.00 Min. : 0.0
1st Qu.:84.0 1st Qu.: 90.00 1st Qu.: 85.00 1st Qu.: 90.00 1st Qu.: 74.0
Median :88.0 Median : 93.00 Median : 90.00 Median : 94.00 Median : 83.0
Mean :87.4 Mean : 92.21 Mean : 89.03 Mean : 92.91 Mean : 81.1
3rd Qu.:92.0 3rd Qu.: 95.00 3rd Qu.: 94.50 3rd Qu.: 96.00 3rd Qu.: 91.0
Max. :99.0 Max. :100.00 Max. :100.00 Max. :100.00 Max. :100.0
hx sw wlfk
Min. : 0.00 Min. : 0.00 Length:775
1st Qu.: 88.00 1st Qu.: 81.00 Class :character
Median : 94.00 Median : 88.00 Mode :character
Mean : 91.57 Mean : 86.26
3rd Qu.: 98.00 3rd Qu.: 93.00
Max. :100.00 Max. :100.00
> #查看数据
> names(cjb)
[1] "xm" "bj" "xb" "yw" "sx" "wy" "zz" "ls" "dl" "wl" "hx" "sw"
[13] "wlfk"
> colnames(cjb)#结果同上
> nrow(cjb)
[1] 775
> ncol(cjb)
[1] 13
> length(cjb)#结果同上
#作必要的类型转换
cjb$bj <- factor(cjb$bj)
cjb$xb <- factor(cjb$xb)
cjb$wlfk <- factor(cjb$wlfk)
str(cjb)
summary(cjb)#再次summary,数据分析总是反复迭代的
结果对比如图所示:
6.数据框记录排序
#数据框记录排序
cjb$zcj <- apply(cjb[,4:12],1,sum)#每个同学的9门课总成绩
order(cjb$zcj,decreasing = T)[1:5]#取到下标
cjb_sorted <- cjb[order(cjb$zcj,decreasing = T),]
View(cjb_sorted)
建模一般分为数据集合测试集
#数据集分为训练集和测试集
set.seed(2012)#设定随机数的种子
n_record <- nrow(cjb)
train_idx <- sample(1:n_record,floor(n_record*0.7))#选出70%个数量,floor向下取整,ceiling向上取整
train_idx <- sample(n_record,n_record*0.7)#简写
length(train_idx)
[1] 542
test_idx <- (1:n_record)[-train_idx]
test_idx <- setdiff(1:n_record,train_idx)#效果同上一个语句
length(test_idx)
[1] 233
#得到测试集和训练集
train_set <- cjb[train_idx,]
test_set <- cjb[-train_idx,]
test_set <- cjb[test_idx,]
#显然,下面这种方式是错误的
train_set <- cjb[sample(n_record,n_record*0.7),]
test_set <- cjb[sample(n_record,n_record*0.3),]#测试集和训练集可能交集非空
#在工业级/商业集应用中,建议不要重复造轮子,直接采用caret等包中训练集和测试集划分
相关函数如createDataPartition()
错题整理:
①访问向量时候,正整数、负整数都可以作为下标,但是不能混用
②语句1:10-1:3的结果是0003336669
在进行向量化运算时,若长度不等,则采用循环补齐的方式进行,相当于1:10-c(1:3,1:3,1)
③sort()函数默认对值进行从低到高排序
④order()排序是先进行强制类型转换,然后按照从低到高的顺序取下标
⑤定序变量,有高下优劣之分,但不能比较差别,例如表征规模、等级的变量
⑥若字符向量partA是列表my_list的第1个组成部分,那么my_list[1]的结果是列表对象,单个[]依旧是列表,[[]]才是组成部分本身,语句my_list$partA与my_list[[1]]和my_list[['partA']]等价
第8章人人都爱tidyverse
tidy整洁的 verse诗篇
tidyverse扩展包,编程理念、风格
library(tidyverse)
-- Attaching packages --------------------------------------- tidyverse 1.3.0 --
√ ggplot2 3.3.2 √ purrr 0.3.4
√ tibble 3.0.3 √ dplyr 1.0.2√ tidyr 1.1.2 √ stringr 1.4.0
√ readr 1.3.1 √ forcats 0.5.0-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()x dplyr::lag() masks stats::lag()
tidyverse扩展包套装:
序号 | 扩展包 | 功能 |
1 | ggplot2 | data visualisation |
2 | dplyr | data manipulation |
3 | tidyr | data tidying |
4 | readr | data import |
5 | purrr | functional programming |
6 | tibble | tibbles,a modern re-imaging of data frames |
7 | stringr | strings |
8 | forcats | for Categorical Variables(Factors) |
重点讲dplyr这个包:
1.管道操作符%>%,二元操作符
lhs(value)%>%rhs(function)
表达式 | 用法 |
x %>%f | f(x) |
x %>% f(y) | f(x,y) |
y %>% f(x, .)#前面的值y不是第一个参数 | f(x,y) |
z %>% f(x,y,arg=.) | f(x,y,arg=z) |
x %>% f %>% g %>%h | h(g(f(x))) |
#查看数据记录
cjb %>%head
xm bj xb yw sx wy zz ls dl wl hx sw wlfk zcj
1 周黎 1101 女 94 82 96 97 97 98 95 94 88 文科 841
2 汤海明 1101 男 87 94 89 95 94 94 90 90 89 文科 822
3 舒江辉 1101 男 92 79 86 98 95 96 89 94 87 文科 816
4 翁柯 1101 女 91 84 96 93 97 94 82 90 83 文科 810
5 祁强 1101 男 85 92 82 93 87 88 95 94 93 文科 809
6 湛容 1101 女 92 82 85 91 90 92 82 98 90 文科 802
cjb%>%head(n=4)#查看前四行,下面这两个语句完全等价
head(cjb,n=4)
xm bj xb yw sx wy zz ls dl wl hx sw wlfk zcj
1 周黎 1101 女 94 82 96 97 97 98 95 94 88 文科 841
2 汤海明 1101 男 87 94 89 95 94 94 90 90 89 文科 822
3 舒江辉 1101 男 92 79 86 98 95 96 89 94 87 文科 816
4 翁柯 1101 女 91 84 96 93 97 94 82 90 83 文科 810
2.dplyr:data manipulation
序号 | 扩展包 | 功能 |
1 | select() | 选择某些列 |
2 | mutate() | 对某些列进行增加或者修改 |
3 | filter() | 针对行,选择某些行 |
4 | arrange() | 排序 |
5 | summarise() | 汇总 |
#选择列
cjb %>%select(xm,yw,sx) %>% head(n=3)#管道化的连续操作
xm yw sx
1 周黎 94 82
2 汤海明 87 94
3 舒江辉 92 79
cjb %>%select(xm,yw,sx) %>% set_names(c("姓名","语文","数学")) %>% head(n=3)
姓名 语文 数学
1 周黎 94 82
2 汤海明 87 94
3 舒江辉 92 79
> cjb %>% select(1,4:12) %>% head(n=3)
xm yw sx wy zz ls dl wl hx sw
1 周黎 94 82 96 97 97 98 95 94 88
2 汤海明 87 94 89 95 94 94 90 90 89
3 舒江辉 92 79 86 98 95 96 89 94 87
> cjb %>% select(xm,yw:sw) %>% head(n=3)
xm yw sx wy zz ls dl wl hx sw
1 周黎 94 82 96 97 97 98 95 94 88
2 汤海明 87 94 89 95 94 94 90 90 89
3 舒江辉 92 79 86 98 95 96 89 94 87
> #列的修改
> cjb %>% mutate_at(vars(bj,xb,wlfk),factor) %>% #强制转换为因子
+ mutate(zcj=rowSums(.[4:12])) %>%
+ arrange(desc(zcj)) %>% #从高到低排序
+ tail(n=2)
xm bj xb yw sx wy zz ls dl wl hx sw wlfk zcj
774 滑亚 1113 男 33 46 30 65 82 76 56 76 59 理科 523
775 张良平 1115 男 0 0 0 0 0 0 0 0 0 理科 0
#成绩表本身并没有该表,生成了一个临时的数据对象
#让更改生效,采用%<>%操作符
cjb %<>% mutate_at(vars(bj,xb,wlfk),factor) %>% #强制转换为因子
mutate(zcj=rowSums(.[4:12])) %>%
arrange(desc(zcj)) #从高到低排序
View(cjb)
#和上述语句等价
cjb <- cjb %>% mutate_at(vars(bj,xb,wlfk),factor) %>% #强制转换为因子
mutate(zcj=rowSums(.[4:12])) %>%
arrange(desc(zcj)) #从高到低排序
#选择行
cjb %>%filter(yw<60)
xm bj xb yw sx wy zz ls dl wl hx sw wlfk zcj
1 滑亚 1113 男 33 46 30 65 82 76 56 76 59 理科 523
2 张良平 1115 男 0 0 0 0 0 0 0 0 0 理科 0
> #只要有不及格的成绩就把这个同学找出来
> cjb %>% filter_at(vars(4:12),any_vars(.<60))
xm bj xb yw sx wy zz ls dl wl hx sw wlfk zcj
1 陈锡生 1107 男 91 89 75 95 100 100 59 86 85 文科 780
2 凌诗雨 1101 女 84 55 95 90 86 100 80 96 86 文科 772
.........
#分组统计,有分组变量也有目标变量
cjb %>% filter(zcj!=0) %>% group_by(xb) %>%
summarise(count=n(),
max=max(zcj),
mean=mean(zcj),
min=min(zcj))
# A tibble: 2 x 5
xb count max mean min
<fct> <int> <dbl> <dbl> <dbl>
1 男 368 885 793. 523
2 女 406 879 797. 647
#tidyr:长宽变换,Key是分组变量,value是目标变量
cjb %>%gather(key = ke_mu,value = cheng_ji,yw:sw) %>%
arrange(xm)
xm bj xb wlfk zcj ke_mu cheng_ji
1 艾春莲 1103 女 文科 713 yw 86
2 艾春莲 1103 女 文科 713 sx 59
3 艾春莲 1103 女 文科 713 wy 87
4 艾春莲 1103 女 文科 713 zz 89
5 艾春莲 1103 女 文科 713 ls 85
6 艾春莲 1103 女 文科 713 dl 92
7 艾春莲 1103 女 文科 713 wl 73
8 艾春莲 1103 女 文科 713 hx 74
9 艾春莲 1103 女 文科 713 sw 68
10 艾阳芳芳 1112 女 理科 820 yw 89
11 艾阳芳芳 1112 女 理科 820 sx 98
12 艾阳芳芳 1112 女 理科 820 wy 91
13 艾阳芳芳 1112 女 理科 820 zz 95
14 艾阳芳芳 1112 女 理科 820 ls 87
15 艾阳芳芳 1112 女 理科 820 dl 94
16 艾阳芳芳 1112 女 理科 820 wl 91
17 艾阳芳芳 1112 女 理科 820 hx 86
18 艾阳芳芳 1112 女 理科 820 sw 89
.......
#按科目进行汇总统计
cjb %>% filter(zcj!=0) %>%
gather(key = ke_mu,value = cheng_ji,yw:sw) %>%
group_by(ke_mu) %>%
summarise(max=max(cheng_ji),
mean=mean(cheng_ji),
median=median(cheng_ji),
min=min(cheng_ji)) %>%
arrange(desc(mean))
# A tibble: 9 x 5
ke_mu max mean median min
<chr> <int> <dbl> <dbl> <int>
1 dl 100 93.0 94 70
2 zz 100 92.3 93 65
3 hx 100 91.7 94 52
4 ls 100 89.1 90 0
5 wy 99 87.5 88 30
6 yw 96 87.4 88 33
7 sw 100 86.4 88 55
8 sx 100 86.2 89 26
9 wl 100 81.2 83 21
错题:①函数n()表示计算本组记录数
第9章最美不过数据框
1.发现数据框背后的规律
数据框(关系表)是最常见的数据对象
发现数据背后的规律
很大程度上就是,发现数据框背后的规律
以机器学习为内核:
数据分析=(约等于)机器学习/数据挖掘
关联+分类+聚类
=寻找关系结构(核心是归类)
2.数据框里有乾坤
分类本质就是函数的映射(按照一定的法则),有监督的学习
数据框里的函数(函数的表示法:列表法)
数据框:函数三种表现形式之一——列表法
一定的法则在数据框中的体现:x和y出现在同一行之中(只是没那么严格)
3.数据框与数据空间
数据集包含n个属性/特征,张成一个n维数据空间
距离关系的远近,在数据空间中形成了自然的结构:簇
无监督的方法:聚类
数据框中列表示维度,行表示点
4.数据框里的关联规则
关联规则A蕴含B:A发生时伴随着B发生
支持度:support(A=》B)=P(A U B)
置信度:confident(A=》B)=P(B|A)=P(A U B)/P(A)
关系表:data.frame|tibble|data.table
一切都是关系结构:关系表几乎可以上升为一个数学概念
题目:① 数据框中的列,从数据库角度讲,是字段;从统计的角度讲,是变量;从机器学习的角度讲,是属性、特征;从数据空间的角度讲,是空间的维度。