1. 首页
  2. R语言

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

【学习】《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课数据科学社区):【学习】《R实战》读书笔记(第五章)

原创文章,作者:ppvke,如若转载,请注明出处:http://www.ppvke.com/archives/29945

联系我们

4000-51-9191

在线咨询:点击这里给我发消息

工作时间:周一至周五,9:30-18:30,节假日休息