打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
中部:执具 | R语言数据分析(北京邮电大学)自整理笔记
userphoto

2024.04.04 湖北

关注

第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.编写函数

fun_name <- function(arg1,arg2=default1,...){ #注释 表达式(循环/判别/.....) return(返回值) }

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

一切都是关系结构:关系表几乎可以上升为一个数学概念

题目:① 数据框中的列,从数据库角度讲,是字段;从统计的角度讲,是变量;从机器学习的角度讲,是属性、特征;从数据空间的角度讲,是空间的维度。

 

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
聊天
Yw
新的一年前似锦@徐yw
第10讲-vf SQL2
SQL一次性插入多条数据
通力电梯板子说明
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服