【学习】《R实战》读书笔记(第五章)

读书会是一种在于拓展视野、宏观思维、知识交流、提升生活的活动。PPV课R语言读书会以“学习、分享、进步”为宗旨,通过成员协作完成R语言专业书籍的精读和分享,达到学习和研究R语言的目的。读书会由辅导老师或者读书会成员推荐书籍,经过讨论确定要读的书,每个月读一本书且要精读,大家一起分享。

第五章 高级数据管理

本章概要

1 数学和统计函数

2 字符函数

3 循环和条件执行

4 用户所写函数

5 聚合和改造数据的方法

本章所介绍内容概括如下。

本章是数据管理高级主题,包含三部分,第一部分,数学、统计、字符操作的函数;第二部分,用户所写函数实现数据管理和分析任务;第三部分,总结、聚合和改造数据的方式。

数据管理的挑战

学生考试数据如图1所示。

图1:学生考试数据

想一想,如何管理上述数据,又如何发现该数据的价值?

数值和字符函数

数值函数,包括数学、统计和概率函数。

常用数学函数如图2所示。

图2:常用数学函数

举例说明如下:

> rm(list=ls())
> abs(-2)
[1] 2
> sqrt(c(1,4,9))
[1] 1 2 3
> ceiling(3.4)
[1] 4
> floor(3.4)
[1] 3
> trunc(3.4)
[1] 3
> round(3.48,digits=1)
[1] 3.5
> signif(3.48, digits=1)
[1] 3
> cos(pi/3)
[1] 0.5
> sin(pi/2)
[1] 1
> tan(pi/4)
[1] 1
> acos(1)
[1] 0
> asin(1)
[1] 1.570796
> atan(1)
[1] 0.7853982
> cosh(1)
[1] 1.543081
> sinh(1)
[1] 1.175201
> tanh(1)
[1] 0.7615942
> acosh(1)
[1] 0
> asinh(1)
[1] 0.8813736
> atanh(1)
[1] Inf
> log(10,base=10)
[1] 1
> log(10)
[1] 2.302585
> log10(10)
[1] 1
> exp(2)
[1] 7.389056

常用统计函数如图3所示:

图3:常用统计函数

举例说明如下:

> mean(c(1,2,3))
[1] 2
> median(c(1,2,3,4))
[1] 2.5
> sd(c(1,2,3,4))
[1] 1.290994
> var(c(1,2,3,4))
[1] 1.666667
> mad(c(1,2,3,4))
[1] 1.4826
> x <- rnorm(100)
> y <- quantile(x, c(.3,.84))
> y
30%        84%
-0.6016543  0.8953049
> rang(c(1,2,3,4))
Error: could not find function “rang”
> range(c(1,2,3,4))
[1] 1 4
> sum(c(1,2,3,4))
[1] 10
> diff(c(1,4,10,100))
[1]  3  6 90
> diff(c(1,4,10,100),lag=2)
[1]  9 96
> min(c(1,2,3,4))
[1] 1
> max(c(1,2,3,40))
[1] 40

计算平均值和标准差的两种方法。

方法一:直接使用统计函数

> rm(list=ls())
> x <- c(1,2,3,4,5,6,7,8)
> mean(x)
[1] 4.5
> sd(x)
[1] 2.44949

方法二:利用统计学对平均值和标准差的定义式

> rm(list=ls())
> x <- c(1,2,3,4,5,6,7,8)
> n <- lenght(x)
Error: could not find function “lenght”
> n <- length(x)
> meanx <- sum(x) / n
> css <- sum((x - meanx)**2)
> sdx <- sqrt(css / (n-1))
> meanx
[1] 4.5
> sdx
[1] 2.44949

拓展:归一化函数scale()

常用与概率学相关的函数。

四个名字:概率密度(d)、概率分布函数(p)、概率分位数(q)、概率随机数(r)。

图4:概率学相关函数

举例说明如下:

> rm(list=ls())
> x <- pretty(c(-3,3), 30)
> y <- dnorm(x)
> plot(x,y,type=”l”,xlab=”Normal Deviate”, ylab=”Density”,yaxs=”i”)
> pnorm(2)
[1] 0.9772499
> qnorm(0.975)
[1] 1.959964

效果图如图5所示。

图5:标准正态分布概率密度曲线

为了进行可重复性实验,我们产生随机数,需要设置种子,举例说明如下:

> runif(5)
[1] 0.07873035 0.93082409 0.05424750 0.96919193 0.52518331
> runif(5)
[1] 0.86842132 0.91613675 0.13160823 0.22718509 0.06111121
> set.seed(100)
> runif(5)
[1] 0.30776611 0.25767250 0.55232243 0.05638315 0.46854928
> set.seed(100)
> funif(5)
Error: could not find function “funif”
> runif(5)
[1] 0.30776611 0.25767250 0.55232243 0.05638315 0.46854928

拓展:可以用MASS包中 mvrnorm(n,mean,sigma)产生多维的随机数。其中mean是每个维度的均值,sigma是由维度形成协方差矩阵(或者相关系数)。

常用字符函数如图6所示。

图6:常用字符函数

其他有用函数如图7所示。

图7:其他有用函数

函数应用于矩阵或者数据框。

举例说明如下:

> rm(list=ls())
> a <- 5
> sqrt(a)
[1] 2.236068
> b <- c(1.234, 2.89, 8.8)
> round(b)
[1] 1 3 9
> c <- matrix(runif(12), nrow=3)
> c
[,1]      [,2]      [,3]      [,4]
[1,] 0.4837707 0.5465586 0.8821655 0.7625511
[2,] 0.8124026 0.1702621 0.2803538 0.6690217
[3,] 0.3703205 0.6249965 0.3984879 0.2046122
> log(c)
[,1]       [,2]       [,3]       [,4]
[1,] -0.7261442 -0.6041138 -0.1253756 -0.2710858
[2,] -0.2077592 -1.7704166 -1.2717028 -0.4019388
[3,] -0.9933863 -0.4700093 -0.9200781 -1.5866390
> mean(c)
[1] 0.5171253
> mean(c[,1])
[1] 0.555498
> mean(c[1,])
[1] 0.6687615

R 中apply()函数,形式如下:

apply(x, MARGIN, FUN, …)

说明:x 表示数据集, MARGIN表示处理方向,1表示按行,2表示按列,FUN表示处理的函数。

举例说明如下:

> rm(list=ls())
> mydata <- matrix(rnorm(30), nrow=6)
> mydata
[,1]       [,2]        [,3]       [,4]       [,5]
[1,] -0.3650827 -0.5896169  1.10361796 -0.5980998 -0.3644158
[2,]  0.4966740  1.4647474  0.94356282 -0.6638578 -0.1372566
[3,]  0.5557346  1.6865777 -0.02198032 -0.7391568  0.5082207
[4,]  0.6712590  1.2236271  1.19638603 -0.8015434 -0.4462014
[5,] -0.9485679  0.3302404 -0.50412749  0.3775060  1.8384113
[6,]  1.1848094 -1.1250266 -0.84634890  0.4576504  0.3178423
> apply(mydata, 1, mean)
[1] -0.162719439  0.420773952  0.397879169  0.368705457  0.218692472
[6] -0.002214703
> apply(mydata, 2, mean)
[1]  0.2658044  0.4984248  0.3118517 -0.3279169  0.2861001
> apply(mydata, 2, mean, trim=0.2)
[1]  0.33964624  0.60724951  0.38026824 -0.40590212  0.08109766

注意:apply()应用与数组类型的数据结构,比方说矩阵。lapply()和sapply()应用于列表类型的数据结构。

数据管理挑战的解法之道

对学生考试数据集管理的挑战解决之道。

程序清单如下。

> rm(list=ls())
> options(digits=2)
> Student <- c(“John Davis”, “Angel 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)
> z <- scale(roster[,2:4])
> score <- apply(z, 1, mean)
> score
[1]  0.56  0.92 -0.86 -1.16 -0.63  0.35 -1.05  1.34  0.70 -0.18
> y <- quantile(score, c(.8,.6,.4,.2))
> y
80%   60%   40%   20%
0.74  0.44 -0.36 -0.89
> y[1]
80%
0.74
> 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
Student Math Science English StringsAsFactors grade
1         John Davis  502      95      25            FALSE     B
2     Angel Williams  600      99      22            FALSE     A
3   Bullwinkle Moose  412      80      18            FALSE     D
4        David Jones  358      82      15            FALSE     F
5  Janice Markhammer  495      75      20            FALSE     D
6     Cheryl Cushing  512      85      28            FALSE     C
7     Reuven Ytzrhak  410      80      15            FALSE     F
8          Greg Knox  625      95      30            FALSE     A
9       Joel England  573      89      27            FALSE     B
10      Mary Rayburn  522      86      18            FALSE     C
> roster <- roster[,c(1:4,6)]
> roster
Student Math Science English grade
1         John Davis  502      95      25     B
2     Angel Williams  600      99      22     A
3   Bullwinkle Moose  412      80      18     D
4        David Jones  358      82      15     F
5  Janice Markhammer  495      75      20     D
6     Cheryl Cushing  512      85      28     C
7     Reuven Ytzrhak  410      80      15     F
8          Greg Knox  625      95      30     A
9       Joel England  573      89      27     B
10      Mary Rayburn  522      86      18     C
> mode(roster[,1])
[1] “numeric”
> as.character(roster[,1])
[1] “John Davis”        “Angel Williams”    “Bullwinkle Moose”
[4] “David Jones”       “Janice Markhammer” “Cheryl Cushing”
[7] “Reuven Ytzrhak”    “Greg Knox”         “Joel England”
[10] “Mary Rayburn”
> mode(roster[,1])
[1] “numeric”
> name <- strsplit((roster$Student), ” “)
Error in strsplit((roster$Student), ” “) : non-character argument
> lastname <- sapply(name, “[", 2)
Error in lapply(X = X, FUN = FUN, ...) : object 'name' not found
> firstname <- sapply(name, "[", 1)
Error in lapply(X = X, FUN = FUN, ...) : object 'name' not found
> roster[,1] <- as.character(roster[,1])
> mode(roster[,1])
[1] “character”
> name <- strsplit((roster$Student), ” “)
> lastname <- sapply(name, “[", 2)
> firstname <- sapply(name, "[", 1)
> roster <- cbind(firstname,lastname, roster[,-1])
> roster <- roster[order(lastname),]
> roster
firstname   lastname Math Science English grade
6      Cheryl    Cushing  512      85      28     C
1        John      Davis  502      95      25     B
9        Joel    England  573      89      27     B
4       David      Jones  358      82      15     F
8        Greg       Knox  625      95      30     A
5      Janice Markhammer  495      75      20     D
3  Bullwinkle      Moose  412      80      18     D
10       Mary    Rayburn  522      86      18     C
2       Angel   Williams  600      99      22     A
7      Reuven    Ytzrhak  410      80      15     F
> roster <- roster[order(lastname, firstname),]
> roster
firstname   lastname Math Science English grade
5      Janice Markhammer  495      75      20     D
6      Cheryl    Cushing  512      85      28     C
2       Angel   Williams  600      99      22     A
4       David      Jones  358      82      15     F
10       Mary    Rayburn  522      86      18     C
8        Greg       Knox  625      95      30     A
9        Joel    England  573      89      27     B
7      Reuven    Ytzrhak  410      80      15     F
1        John      Davis  502      95      25     B
3  Bullwinkle      Moose  412      80      18     D

控制流程

通常情况下,程序从上往下依次执行。然则,有时候需要重复执行或是按条件执行,这需要控制流程来实现。

重复与循环

方法一:for,形式如下:

for(var in seq)  statement
举例说明如下:
> rm(list=ls())
> for(i in 1:10) print(“Hello”)
[1] “Hello”
[1] “Hello”
[1] “Hello”
[1] “Hello”
[1] “Hello”
[1] “Hello”
[1] “Hello”
[1] “Hello”
[1] “Hello”
[1] “Hello”

方法二:while,形式如下:

while(cond) statement
举例说明如下:
> rm(list=ls())
> i <- 10
> while(i>0) {print(“hello”);i<-i-1}
[1] “hello”
[1] “hello”
[1] “hello”
[1] “hello”
[1] “hello”
[1] “hello”
[1] “hello”
[1] “hello”
[1] “hello”
[1] “hello”

条件执行

使用方式如下

if(cond) statement
if(cond) statement1 esle statement2
ifelse(cond, statement1, statement2)
switch(expr, …)

举例说明如下:

> feeling <- c(“sad”, “afraid”)
> for(i in feeling)
+ print(switch(i, happy=”I am happy”,
+ afraid=”I am fear”,
+ sad = “I am sad”,
+ angry = “Calm down now”))
[1] “I am sad”
[1] “I am fear”

用户所写函数

用户可以根据具体问题自定义函数,自定义函数形式如下:

myfunction <- function(arg1,arg2,arg3,…) {

statements

return(object) }

举两个例子说明如下:

例子一:创建一个进行两位数加法、减法、乘法和除法的运算函数。

> myfun <- function(x1,x2)
+ {add = x1 + x2;
+ sub = x1 - x2;
+ mul = x1 * x2;
+ div = x1 / x2;
+ result <- c(add, sub, mul, div);
+ return(result)}
> myfun(10,2)
[1] 12  8 20  5

例子二:创建一个用户自定义的统计函数。

> rm(list=ls())
> mystats <- function(x, parametric=TRUE, print=FALSE) {
+ if(parametric) {
+ center <- mean(x); spread <- sd(x)
+ } else {
+ center <- median(x); spread <- mad(x)
+ }
+ if(print & parametric) {
+ cat(“Mean=”, center, “\n”, “DS=”, spread, “\n”)
+ } else if (print & !parametric) {
+ cat(“Median=”, center, “\n”, “MAD=”, spread, “\n”)
+ }
+ result <- list(center=center, spread=spread)
+ return(result)
+ }
> set.seed(1234)
> x <- rnorm(500)
> y <- mystats(x)
> y
$center
[1] 0.0018
$spread
[1] 1
> y <-mystats(x, parametric=FALSE, print=TRUE)
Median= -0.021
MAD= 1

数据集合和改造

转置

对矩阵或者数据框中的内容转置,即行变为列,列变为行。

举例说明如下:

> rm(list=ls())
> cars <- mtcars[1:5, 1:4]
> cars
mpg cyl disp  hp
Mazda RX4          21   6  160 110
Mazda RX4 Wag      21   6  160 110
Datsun 710         23   4  108  93
Hornet 4 Drive     21   6  258 110
Hornet Sportabout  19   8  360 175
> t(cars)
Mazda RX4 Mazda RX4 Wag Datsun 710 Hornet 4 Drive Hornet Sportabout
mpg         21            21         23             21                19
cyl          6             6          4              6                 8
disp       160           160        108            258               360
hp         110           110         93            110               175

拓展:

1 aggreate()函数。

2 R的reshape包中函数数据进行改造。

总结

1 基于R中丰富的函数管理数据,比如数学函数、统计函数、字符函数。

2 R中流程控制结构,重复与循环和条件选择。

3 R中用户所写函数,为了解决某个数据分析任务自定义函数实现和完成。

4 数据的聚合和改造

Resource

1 http://www.wangluqing.com/2014/06/r-in-action-note6/ ‎

2 《R in action》第一部分第五章

本栏目文章由PPV课R语言读书会提供,转载请注明来自PPV课R语言读书会。

版权所有,违者必究!

原文发布于微信公众号 - PPV课数据科学社区(ppvke123)

原文发表时间:2014-07-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏落影的专栏

程序员进阶之算法练习(十)2016CCPC东北重现赛

前言 最近几个月在做逻辑思维僵化的康复训练,刚好大学的教练说能争取到一个比赛的名额,于是兴致勃勃找了原来的队友和一个老学长,愉快的报名参加比赛。 于是开始...

36550
来自专栏落影的专栏

程序员进阶之算法练习(十九)

前言 这周很忙,但是越忙的时候反而越喜欢抽空做算法题。 欢迎关注algorithm文集。 这次A、B、C都是很合适的面试题。 正文 A. Memory ...

38460
来自专栏常用编程思想与算法

常用编程思想与算法

本文是在阅读Aditya Bhargava先生算法图解一书所做的总结,文中部分代码引用了原文的代码,在此感谢Aditya Bhargava先生所作出的这么简单的...

23510
来自专栏窗户

围棋规则的计算机实现

  提到这个名字,很多人会想到前段时间让全世界振奋的围棋人工智能Alphago,想曾经我也了解过一些围棋的AI。我也正想花点时间说说alphago相关的东西,包...

296100
来自专栏北京马哥教育

用Python分析苹果公司股价数据

❈ 作者:酱油哥,清华程序猿、IT非主流 专栏地址:https://zhuanlan.zhihu.com/c_147297848 ❈ 要点抢先看 1.csv数...

36460
来自专栏C/C++基础

维诺图(Voronoi Diagram)分析与实现

又叫泰森多边形或Dirichlet图,它是由一组由连接两邻点直线的垂直平分线组成的连续多边形组成。

45610
来自专栏WOLFRAM

九宫格数独游戏

27080
来自专栏落影的专栏

程序员进阶之算法练习(十八)

前言 最近在接触新知识,也是选择2017年的方向。 其他文集更新会放缓,没有学习就没有心得,肚中无墨就无从下笔。 但是算法练习还是挺好玩的,欢迎关注algo...

35950
来自专栏数据结构与算法

P1613 跑路

题目描述 小A的工作不仅繁琐,更有苛刻的规定,要求小A每天早上在6:00之前到达公司,否则这个月工资清零。可是小A偏偏又有赖床的坏毛病。于是为了保住自己的工资,...

29990
来自专栏北京马哥教育

用Python分析苹果公司股价数据

专栏地址:https://zhuanlan.zhihu.com/c_147297848

54100

扫码关注云+社区

领取腾讯云代金券