美文网首页R语言
《R语言实战》学习笔记

《R语言实战》学习笔记

作者: 弹跳骑士 | 来源:发表于2017-07-27 15:06 被阅读1641次

    2017年夏天开始学习R语言。

    第1章 R语言介绍

    1.1 R的获取和安装

    下载Rgui:http://cran.r-project.org
    可以通过安装包(package)的可选模块来增强R的功能。
    下载RStudio:https://www.rstudio.com/products/rstudio/download/#download

    1.3 R的使用

    • R是一种区分大小写的解释性语言。
    • R使用<-作为赋值符号,而不是传统的=。
    • 注释由#开头。
    • R不提供多行注释功能,可以用if(FALSE){}存放被忽略的代码。
    • R会自动拓展数据结构以容纳新值。
    • R的下标从1开始。
    • 变量无法被声明,它们在首次赋值时生成。
    • Google's R Style Guide: https://google.github.io/styleguide/Rguide.xml
    • 搜索“来自Google的R语言编码风格指南”可以找到这份文档的中文版
    • R programming for those coming from other languages: https://www.johndcook.com/R_language_for_programmers.html

    1.3.1 获取帮助 P10

    • help.start() 打开帮助文档首页

    1.3.2 工作空间 P11

    • getwd() 查看当前工作目录
    • setwd() 设定当前工作目录
    • dir.create() 创建新目录
    • 路径使用正斜杆/
    • 命令的历史纪录保存到文件.Rhistory
    • 工作空间保存到当前目录中的文件.RData
    • q() 退出R

    1.3.3 输入和输出

    • 输入:source("filename")
    • 文本输出:sink("filename")
      参数append = TRUE追加文本而非覆盖
      参数split = TRUE将输出同时发送到屏幕和输出文件中
      无参数调用sink() 仅向屏幕返回输出结果
    • 图形输出 P12

    1.5 批处理 P15

    1.6 将输出用为输入:结果的重用 P16

    lmfit <- lm(mpg~wt, date = mtcars)

    第2章 创建数据集

    2.1 数据集的概念

    数据构成的矩形数组,行表示观测,列表示变量。

    2.2 数据结构

    2.2.1 向量

    向量是用于存储数值型、字符型或逻辑型数据的一维数组。
    创建向量:c()

    • 单个向量中的数据必须拥有相同的类型或模式(数值、字符、逻辑)
    • 标量是只含一个元素的向量,用于保存常量
    • 访问向量中的元素:
    > a <- c("k", "j", "h", "a", "b", "m")
    > a[3]
    [1] "h"
    > a[c(1,3,5)]
    [1] "k" "h" "b"
    > a[1,3,5]
    Error in a[1, 3, 5] : 量度数目不对
    > a[2:6]
    [1] "j" "h" "a" "b" "m"
    

    2.2.2 矩阵 P22

    矩阵是一个二维数组,每个元素拥有相同的模式。
    创建矩阵:matrix(矩阵元素, nrow = 行数, ncol = 列数, byrow = FALSE 默认按列填充<可选>, dimnames = list(行名, 列名)<可选>)

    > y <- matrix(1:20, nrow = 5, ncol = 4)
    > y
         [,1] [,2] [,3] [,4]
    [1,]    1    6   11   16
    [2,]    2    7   12   17
    [3,]    3    8   13   18
    [4,]    4    9   14   19
    [5,]    5   10   15   20
    > cells <- c(1, 26, 24, 68)
    > rnames <- c("R1", "R2")
    > cnames <- c("C1", "C2")
    > mymatrix <- matrix(cells, nrow = 2, ncol = 2, byrow = TRUE, dimnames = list(rnames, cnames))
    > mymatrix
       C1 C2
    R1  1 26
    R2 24 68
    
    

    矩阵下标的使用:
    X[i, ] 矩阵X中的第i行
    X[, j] 矩阵X中的第j列
    X[i, j] 矩阵X中的第i行第j个元素
    选择多行或多列,下标i和j可为数值型向量。

    > x <- matrix(1:10, nrow = 2)
    > x
         [,1] [,2] [,3] [,4] [,5]
    [1,]    1    3    5    7    9
    [2,]    2    4    6    8   10
    > x[2, ]
    [1]  2  4  6  8 10
    > x[, 2]
    [1] 3 4
    > x[1, 4]
    [1] 7
    > x[1, c(4,5)]
    [1] 7 9
    

    2.2.3 数组

    数组和矩阵类似,但是维度可以大于2。
    创建数组:array(vector, dimensions, dimnames<可选>)

    > dim1 <- c("A1", "A2")
    > dim2 <- c("B1", "B2", "B3")
    > dim3 <- c("C1", "C2", "C3", "C4")
    > z <- array(1:24, c(2,3,4), dimnames = list(dim1, dim2, dim3))
    > z
    , , C1
    
       B1 B2 B3
    A1  1  3  5
    A2  2  4  6
    
    , , C2
    
       B1 B2 B3
    A1  7  9 11
    A2  8 10 12
    
    , , C3
    
       B1 B2 B3
    A1 13 15 17
    A2 14 16 18
    
    , , C4
    
       B1 B2 B3
    A1 19 21 23
    A2 20 22 24
    

    2.2.4 数据框

    创建数据框:data.frame(col1, col2, col3, ...)

    > patientID <- c(1, 2, 3, 4)
    > age <- c(25, 34, 28, 52)
    > diabetes <- c("Type1", "Type2", "Type1", "Type1")
    > status <- c("Poor", "Improved", "Excellent", "Poor")
    > patientdata <- data.frame(patientID, age, diabetes, status)
    > patientdata
      patientID age diabetes    status
    1         1  25    Type1      Poor
    2         2  34    Type2  Improved
    3         3  28    Type1 Excellent
    4         4  52    Type1      Poor
    

    选取数据框中的元素:

    > patientdata[1:2]
      patientID age
    1         1  25
    2         2  34
    3         3  28
    4         4  52
    > patientdata[c("diabetes", "status")]
      diabetes    status
    1    Type1      Poor
    2    Type2  Improved
    3    Type1 Excellent
    4    Type1      Poor
    > patientdata$age
    [1] 25 34 28 52
    > table(patientdata$diabetes, patientdata$status)
           
            Excellent Improved Poor
      Type1         1        0    2
      Type2         0        1    0
    
    • attach()、detach()和with()
      函数attach() 可将数据框添加到R的搜索路径中
    summary(mtcars$mpg)
    plot(mtcars$mpg, mtcars$disp)
    plot(mtcars$mpg, mtcars$wt)
    可写成
    attach(mtcars)
        summary(mpg)
        plot(mpg, disp)
         plot(mpg, wt)
    detach(mtcars)
    

    函数detach() 将数据框从搜索路径中移除。(可省略,为保持良好的编程习惯还是要写。)
    环境中有重名对象时使用函数with() :

    with(mtcars,{
        print(summary(mpg))
        plot(mpg, disp)
        plot(mpg, wt)
    })
    若要创建在with() 结构意外的对象,使用特殊赋值符<<-代替<-
    with(mtcars, {
        keepstats <<- summary(mpg)
    })
    
    • 实例标识符
      实例标识符可通过数据框操作函数中的rowname选项指定。
    patientdata <- data.frame(patientID, age, diabetes, status, row.names = patientID)
    

    2.2.5 因子

    变量可归结为名义型、有序型或连续型变量。

    • 名义型变量没有顺序之分。如:Diabetes(Type1、Type2)
    • 有序型变量表示一种顺序关系而非数量关系。如:Status(poor、improved、excellent)
    • 连续型变量呈现为某个范围内的任意值。如:Age
      因子:类别(名义型)变量和有序类别(有序型)变量。
      对于名义型变量:
    diabetes <- c("Type1", "Type2", "Type1", "Type1")
    语句diabetes <- factor(diabetes)将此向量存储为(1, 2, 1, 1)
    并在内部将其关联为1 = Type1和2 = Type2(具体赋值根据字母顺序而定)
    

    对于有序型变量,需要为函数factor() 指定参数ordered = TRUE:

    satatus <- c("Poor", "Improved", "Excellent", "Poor")
    语句status <- factor(status, ordered = TRUE)会将向量编码为(3, 2, 1, 3)
    默认为字母顺序排序,若要指定排序:
    status <- factor(status, order = TRUE, levels = c("Poor", "Improved", "Excellent"))
    

    对于数值型变量:

    如果男性编码成1,女性编码成2:
    sex <- factor(sex, levels = c(1, 2), labels = c("Male", "Female"))
    标签"Male" 和"Female” 将代替1和2在结果中输出
    

    因子的使用:

    > patientID <- c(1, 2, 3, 4)
    > age <- c(25, 34, 28, 52)
    > diabetes <-  c("Type1", "Type2", "Type1", "Type1")
    > status <- c("Poor", "Improved", "Excellent", "Poor")
    > diabetes <- factor(diabetes)
    > status <- factor(status, ordered = TRUE)
    > patientdata <- data.frame(patientID, age, diabetes, status)
    > str(patientdata) #显示数据框内部编码结构
    'data.frame':   4 obs. of  4 variables:
     $ patientID: num  1 2 3 4
     $ age      : num  25 34 28 52
     $ diabetes : Factor w/ 2 levels "Type1","Type2": 1 2 1 1
     $ status   : Ord.factor w/ 3 levels "Excellent"<"Improved"<..: 3 2 1 3
    > summary(patientdata) #显示对象的统计概要(区别对待各个变量)
       patientID         age         diabetes       status 
     Min.   :1.00   Min.   :25.00   Type1:3   Excellent:1  
     1st Qu.:1.75   1st Qu.:27.25   Type2:1   Improved :1  
     Median :2.50   Median :31.00             Poor     :2  
     Mean   :2.50   Mean   :34.75                          
     3rd Qu.:3.25   3rd Qu.:38.50                          
     Max.   :4.00   Max.   :52.00    
    

    2.2.5 列表

    列表就是一些对象的有序集合
    创建列表:
    mylist <- list(object1, objext2, ...)
    mylist <- list(name1 = object1, name2 = object2, ...)

    > g <- "My First List"
    > h <- c(25, 26, 18, 39)
    > j <- matrix(1:10, nrow = 5)
    > k <- c("one", "two", "three")
    > mylist <- list(title = g, ages = h, j, k)
    > mylist
    $title
    [1] "My First List"
    
    $ages
    [1] 25 26 18 39
    
    [[3]]
         [,1] [,2]
    [1,]    1    6
    [2,]    2    7
    [3,]    3    8
    [4,]    4    9
    [5,]    5   10
    
    [[4]]
    [1] "one"   "two"   "three"
    
    > mylist[[2]]
    [1] 25 26 18 39
    > mylist[["ages"]]
    [1] 25 26 18 39
    
    

    2.3 数据的输入

    2.3.1使用键盘输入数据

    1. R内置文本编辑器
    > mydata <- data.frame(age = numeric(0), gender = character(0), weight = numeric(0))
    > mydata <- edit(mydata)
    #语句mydata <- edit(mydata) 可以简便写为fix(mydata)
    
    1. 代码中直接嵌入数据
    > mydatatxt <- "
    + age gender weight
    + 25 m 166
    + 30 f 115
    + 18 f 120
    + "
    > mydatatxt <- read.table(header = TRUE, text = mydatatxt)
    

    2.3.2 从带分隔符的文本导入数据 P33

    mydataframe <- read.table(file, options)
    其中file是一个带分隔符的ASCII文本文件,options是控制如何处理数据的选项。

    2.3.3 导入Excel数据

    • 最好方式:在Excel中导出为逗号分隔文件csv,再用前文描述导入R。
    • 直接导入:xlsx包、xlsxjars和rJava包。P35

    2.3.4 导入XML数据

    www.omegahat.org/RSXML

    2.3.5 从网页抓取数据

    2.3.6 导入SPSS数据 P36

    2.3.7 导入SAS数据 P37

    2.3.8 导入Stata数据

    library(foreign)
    mydataframe <- read.dta("mydata.dta")
    

    2.3.9 导入NetCDF数据 P38

    2.3.10 导入HDF5数据 p38

    2.3.11 访问数据库管理系统 P38

    2.3.12 通过Stat/ Transfer导入数据

    www.stattransfer.com 数据转换应用程序。

    2.4 数据集的标注

    2.4.1 变量标签

    就是重命名:

    names(patientdata)[2] <- "Age at hospitalization (in years)"
    

    2.4.2 值标签

    如果男性编码成1,女性编码成2:
    sex <- factor(sex, levels = c(1, 2), labels = c("Male", "Female"))
    标签"Male" 和"Female” 将代替1和2在结果中输出
    

    2.5 处理数据对象的实用函数

    P41

    第3章 图形初阶

    3.1 使用图形

    保存图形:代码、用户图形界面保存。P44

    3.3 图形参数

    修改图形的特征。

    > opar <- par(no.readonly = TRUE)
    > par(lty = 2, pch = 17)
    > par(opar)
    

    3.3.1 符号和线条

    • pch 指定绘制点时只用的符号
    • cex 指定符号的大小
    • lty 指定线条的类型
    • lwd 指定线条的宽度
    > plot(dose, drugA, type = "b", lty = 3, lwd = 3, pch = 15, cex = 2)
    

    3.3.2 颜色

    #RColorBrewer创建吸引人的颜色配对
    > install.packages("RColorBrewer")
    > library(RColorBrewer)
    > n <- 7
    > mycolors <- brewer.pal(n,"Set1")
    > barplot(rep(1, n), col = mycolors)
    #彩虹渐变色
    > n <- 10
    > mycolors <- rainbow(n)
    > pie(rep(1, n), labels = mycolors, col = mycolors)
    #10阶灰度色
    > mygrays <- gray(0:n/n)
    > pie(rep(1, n), labels = mygrays, col = mygrays)
    

    3.3.3 文本属性 P50

    3.3.4 图形尺寸与边界尺寸

    使用图形参数控制图形外观:

    > dose <- c(20, 30, 40, 45, 60)
    > drugA <- c(16, 20, 27, 40, 60)
    > drugB <- c(15, 18, 25, 31, 40)
    > opar <- par(no.readonly = TRUE)
    > par(pin = c(2, 3))
    > par(lwd = 2, cex = 1.5)
    > par(cex.axis = .75, font.axis = 3)
    > plot(dose, drugA, type = "b", pch = 19, lty = 2, col = "red")
    > plot(dose, drugB, type = "b", pch = 23, lty = 6, col = "blue", bg = "green")
    > par(opar)
    

    3.4 添加文本、自定义坐标轴和图例

    3.4.1 标题

    title(main = "main title", col.main = "red", sub = "subtitle", col.sub = "blue", xlab = "x-axis laber", tlab = "y-axis laber", col.lab = "green", cex.lab = 0.75)
    

    3.4.2 坐标轴 P54

    axis(side, at = , labers = , pos, lty = , col = , las = , tck = , ... )
    
    > x <- c(1:10)
    > y <- x
    > z <- 10 / x
    > opar <- par(no.readonly = TRUE)
    > par(mar = c(5, 4, 4, 8) + 0.1)
    > plot(x, y, type = "b", pch = 21, col = "red", yaxt = "n", lty = 3, ann = FALSE)
    > lines(x, z, type = "b", pch = 22, col = "blue", lty = 2)
    > axis(2, at = x, labels = x, col.axis = "red", las =2)
    > axis(4, at = z, labels = round(z, digits = 2), col.axis = "blue", las = 2, cex.axis = 0.7, tck = -.01)
    > mtext("y = 1 / x", side = 4, line = 3, cex.lab = 1, las = 2, col = "blue")
    > title("An Example of Creative Axes", xlab = "X values", ylab = "Y = X")
    > par(opar)
    

    3.4.3 参考线

    abline(h = tvalues, v = xvalues)
    abline(h = c(1, 5, 7))
    abline(v = seq(1, 10, 2), lyt = 2, col = "blue")
    

    3.4.4 图例

    legend(location, title, legend, ...)
    
    > dose <- c(20, 30, 40, 45, 60)
    > drugA <- c(16, 20, 27, 40, 60)
    > drugB <- c(15, 18, 25, 31, 40)
    > opar <- par(no.readonly = TRUE)
    > par(lwd = 2, cex = 1.5, font.lab = 2)
    > plot(dose, drugA, type = "b", pch = 15, lty = 1, col = "red", ylim = c(0, 60), main = "Drug A vs. Drug B", xlab = "Drug Dosage", ylab = "Drug Response")
    > lines(dose, drugB, type = "b", pch = 17, lty = 2, col = "blue")
    > abline(h = c(30), lwd = 1.5, lty = 2, col = "gray")
    > minor.tick(nx = 3, ny = 3, tick.ratio = 0.5)
    > legend("topleft", inset = 0.5, title = "Drug Type", c("A","B"),lty = c(1, 2), pch = c(15, 17), col = c("red", "blue"))
    > par(opar)
    

    3.4.5 文本标注

    text(location, "text to place", pos, ...)
    mtext("text to place", side, line = n, ...)
    

    3.4.6 数学标注 P61

    plotmath()

    3.5 图形的组合

    attach(mtcars)
    opar <- par(no.readonly = TRUE)
    par(mfrow = c(2, 2))
    plot(...)
    plot(...)
    hist(...)
    boxplot(...)
    par(opar)
    detach(mtcars)
    
    attach(mycars)
    layout(matrix(c(1, 1, 2, 3), 2, 2, byrow = TRUE), widths = c(3,1), heights = c(1, 2))
    hist(...)
    hist(...)
    hist(...)
    detach(mtcars)
    

    图形布局的精细控制

    opar <- par(no.readonly = TRUE)
    par(fig = c(0, 0.8, 0, 0.8))
    plot(...)
    par(fig = c(0, 0.8, 0.55, 1), new = TRUE)
    boxplot(...)
    par(fig = c(0.65, 1, 0, 0.8, new = TRUE))
    boxplot(...)
    par(opar)
    

    第4章 基本数据管理

    4.2 创建新变量

    可能需要创建新变量或者对现有的变量进行变换。变量名 <- 表达式

    mydata <- data.frame(x1 = c(2, 2, 6, 4), x2 = c(3, 4, 2, 8))
    #方式一
    mydata$sumx <- mydata$x1 + mydata$x2
    mydata$meanx <- (mydata$x1 + mydata$x2) / 2
    #方式二
    attach(mydata)
    mydata$sumx <- x1 + x2
    mydata$meanx <- (x1 + x2) / 2
    detach(mydata)
    #方式三
    mydata <- transform(mydata, sumx = x1 +x2, meanx = (x1 + x2) / 2)
    

    4.3 变量的重编码

    leadership <- within(leadership, {
                                          agecat <- NA
                                          agecat[age >75] <- "Elder"
                                          agecat[age >= 75 & age <= 75] <- "Middle Aged"
                                          agecat[age < 55] <- "Young"})
    

    其他实用的变量重编码函数:car包中的recode()、doBy包中的recodevar()、R自带的cut()。

    4.4 变量的重命名

    1. fix(leadership)调用交互式编辑器。
    2. names()函数重命名变量:
    names(leadership)[2] <- "testDate"
    names(leadership)[6:10] <- c("item1", "item2", "item3", "item4", "item5") 
    
    1. plyr包中的rename()函数可用于修改变量名:
    library(plyr)
    leadership <- rename(leadership, c(manager = "managerID", date = "testDate"))
    

    4.5 缺失值

    缺失值以符号NA(Not Available,不可用)表示。
    函数is.na()允许检测缺失值是否存在。

    y <- c(1, 2, 3, NA)
    is.na(y)
    返回c(FALSE, FALSE, FALSE, TRUE)
    
    is.na(leadership[,6:10])
    #将数据框限定到第6到第10列
    

    识别无限的或者不可能出现的数值用is.infinite()或is.nan()。

    4.5.1 重编码某些值为缺失值

    要确保所有的缺失数据已在分析之前被妥善地编码为缺失值。

    leadership$age[leadership$age == 99] <- NA
    

    4.5.2 在分析中排除缺失值

    • 多数的数值函数拥有一个na.rm = TRUE选项,可以在计算之前移除缺失值并使用剩余值进行计算:
    x <- c(1, 2, NA, 3)
    y <- sum(x, na.rm = TRUE)
    
    • na.omit()可以删除所有含有缺失数据的行:
    newdata <- na.omit(leadership)
    

    4.6 日期值

    as.Date(x, "input_format"),默认输入格式为yyyy-mm-dd。

    dates <- as.Date(strDates, "%m/%d/%Y")
    myformat <- "%m/%d/%y"
    leadership$date <- as.Date(leadership$date, myformat)
    

    Sys.Date()返回当天的日期。
    date()返回当前的日期和时间。
    可以使用函数format(x, format = "output_format")来输出指定格式的日期值,并且可以提取日期值中的某些部分:

    today <- Sys.Date()
    format(today, format = "%B %d %Y")
    format(today, format = "%A")
    

    R的内部存储日期是使用自1970年1月1日以来的天数表示的,更早的日期表示为负数。可以在日期值上执行算术运算:

    > startdate <- as.Date("2004-02-13")
    > enddate <- as.Date("2011-01-22")
    > days <- enddate - startdate
    > days
    Time difference of 2535 days
    
    > today <- Sys.Date()
    > dob <- as.Date("1996-09-05")
    > difftime(today, dob, units = "days")
    Time difference of 7640 days
    

    4.6.1 将日期转换为字符型变量

    strDates <- as.character(dates)
    

    4.7 类型转换 P78

    > a <- c(1, 2, 3)
    > a
    [1] 1 2 3
    > is.numeric(a)
    [1] TRUE
    > is.vector(a)
    [1] TRUE
    > a <- as.character(a)
    > a
    [1] "1" "2" "3"
    > is.numeric(a)
    [1] FALSE
    > is.vector(a)
    [1] TRUE
    > is.character(a)
    [1] TRUE
    

    4.8 数据排序

    order()函数对一个数据框进行排序,默认升序,在排序变量前边加一个减号可得降序。

    newdata <- leadership[order(leadership$age),]
    #创建新的数据集,其中各行依照经理人的年龄升序排序
    attach(leadership)
    newdata <- leadership[order(gender, age), ]
    detach(leadreship)
    #各行依照女性到男性、同样性别中按年龄升序排序
    attach(leadership)
    newdata <- leadership[order(gender, -age), ]
    detach(leadreship)
    #各行依照女性到男性、同样性别中按年龄降序排序
    

    4.9 数据集的合并

    4.9.1 向数据框添加列

    横向合并两个数据框(数据集),使用merge()函数。

    total <- merge(dataframeA, dataframeB, by = "ID")
    
    total <- merge(dataframeA, dataframeB, by = c("ID", "Country"))
    
    #如果直接横向合并两个矩阵或者数据框并且不指定一个公共索引用cbind()
    total <- cbind(A, B)
    #每个对象必须拥有相同的行数,以同顺序排序
    

    4.9.3 向数据框添加行

    纵向合并两个数据框(数据集)使用rbind()函数:

    total <- rbind(dataframeA, dataframeB)
    

    两个数据框必须拥有相同的变量,不过顺序不必一定相同。

    4.10 数据集取子集

    4.10.1 选入(保留)变量

    newdata <- leadership[, c(6:10)]
    
    myvars <- c("q1", "q2", "q3", "q4", "q5")
    newdata <- leadership[myvars]
    
    myvars <- paste("q", 1:5, sep=" ")
    newdata <- leadership[myvars]
    

    4.10.2 剔除(丢弃)变量

    myvars <- names(leadership) %in% c("q3", "q4")
    newdata <- leadership[!myvars]
    
    #已知q3和q4是第8个和第9个变量的情况下,可以使用语句:
    newdata <- leadership[c(-8, -9)]
    
    #设置q3和q4两列为未定义(NULL)亦是一种删除方式,NULL和NA是不同的
    leadership$q3 <- leadership$q4 <-NULL
    

    4.10.3 选入观测

    newdata <- leadership[1:3, ]
    
    newdata <- leadership[leadership$gender == "M" & leadership$age >30,]
    
    leadership$data <- as.Date(LEADERSHIP$DATE, "%m/%d/%y")
    startdate <- as.Date("2009-01-01")
    enddate <- as.Date("2009-10-31")
    newdata <- leadership[which(leadership$date) >= startdate & leadership$date <= enddate), ]
    

    4.10.4 subset()函数

    选择变量和观测最简单的方法。

    newdata <- subset(leadership, age >= 35 | age < 24, select = c(q1, q2, q3, q4))
    newdate <- subset(leadership, gender == "M" & age > 25, select = gender:q4)
    

    4.10.5 随机抽样

    sample()函数中的第一个参数是一个由要从中抽样的元素组成的向量,第二个参数是要抽取的元素数量, 第三个参数表示无放回抽样。

    mysample() <- leadership[sample(1:nrow(leadership), 3, replace = FALSE), ]
    

    4.11 使用SQL语句操作数据框

    library(sqldf)
    newdf <- sqldf("select * from mtcars where carb = 1 order by mpg", row.names = TRUE)
    
    sqldf("select avg(mpg) as avg_mpg, avg(disp) as avg_disp, gear from mtcars where cyl in (4, 6) group by gear")
    

    第5章 高级数据管理

    5.2 数值和字符处理函数

    5.2.1 数学函数 P86

    5.2.2 统计函数 P88

    5.2.3 概率函数 P90

     R中概率函数形如[dpqr]distribution_abbreviation()
    #位于z = 1.96左侧的标准正态曲线下方面积是多少?
    > pnorm(1.96)
    [1] 0.9750021
    #均值为500,标准差为100的正态分布的0.9分位点值为多少?
    > qnorm(.9, mean = 500, sd = 100)
    [1] 628.1552
    #生成50个均值为50,标准差为10的正态随机数
    > rnorm(50, mean = 50, sd = 10)
    
    1. 设定随机数种子
      set.seed()显示指定种子。runif()生成0到1区间上服从均匀分布的伪随机数。
    > runif(5)
    [1] 0.6509069 0.9809366 0.2417076 0.4011322 0.1121973
    > runif(5)
    [1] 0.95703624 0.86061820 0.09811243 0.74588111 0.75219763
    > set.seed(1234)
    > runif(5)
    [1] 0.1137034 0.6222994 0.6092747 0.6233794 0.8609154
    > runif(5)
    [1] 0.640310605 0.009495756 0.232550506 0.666083758 0.514251141
    > set.seed(1234)
    > runif(5)
    [1] 0.1137034 0.6222994 0.6092747 0.6233794 0.8609154
    
    1. 生成多元正态数据
      MASS包中的mvrnorm()函数:mvrnorm(n, mean, sigma)
      其中n是想要的样本大小,mean为均值向量,而sigma是方差-协方差矩阵(或相关矩阵)
    > library(MASS)
    > options(digits = 3)
    > set.seed(1234)
    
    > mean <- c(230.7, 146.7, 3.6)
    > sigma <- matrix(c(15360.8, 6721.2, -47.1, 6721.2, 4700.9, -16.5, -47.1, -16.5, 0.3), nrow = 3, ncol = 3)
    
    > mydata <- mvrnorm(500, mean, sigma)
    > mydata <- as.data.frame(mydata)
    > names(mydata) <- c("y", "x1", "x2")
    
    > dim(mydata)
    [1] 500   3
    > head(mydata, n = 10)
           y    x1   x2
    1   98.8  41.3 3.43
    2  244.5 205.2 3.80
    3  375.7 186.7 2.51
    4  -59.2  11.2 4.71
    5  313.0 111.0 3.45
    6  288.8 185.1 2.72
    7  134.8 165.0 4.39
    8  171.7  97.4 3.64
    9  167.2 101.0 3.50
    10 121.1  94.5 4.10
    

    5.2.4 字符处理函数 P93

    5.2.5 其他实用函数 P94

    5.2.6 将函数应用于矩阵和数据框

    apply()函数:apply(x, MARGIN, FUN, ...)
    x为数据对象, MARGIN是维度的下标, FUN是制定的函数,...包括了任何想传递给FUN的参数。在矩阵或数据框中,MARGIN = 1表示行, MARGIN = 2表示列。

    5.4 控制流

    5.4.1 重复和循环

    1. for结构
    #for (var in seq) statement
    for (i in 1:10) print("Hello")
    
    1. while结构
    #while (cond) statement
    i <- 10
    while (i > 0) {print("Hello"); i <- i - 1}
    

    5.4.2 条件执行

    1. if-else结构
    #if (cond) statement
    #if (cond) statement1 else statement2
    if (is.character(grade)) grade <- as.factor(grade)
    if (!is.factor(grade)) grade <- as.factor(grade) else print("Grade already is a factor")
    
    1. ifelse结构
    #ifelse(cond, statement1, statement2)
    ifelse(score > 0.5, print("Passed"), print("Failed"))
    outcome <- ifelse(score > 0.5, "Passed", "Failed")
    
    1. switch结构
    #switch(expr, ...)
    > feelings <- c("sad", "afraid")
    > for (i in feelings)
    +     print(
    +         switch(i, happy = "I am glad you are happy",
    +                   afraid = "There is nothing to fear",
    +                   sad = "Cheer up",
    +                   angry = "Calm down now"
    +         )
    +     )
    [1] "Cheer up"
    [1] "There is nothing to fear"
    

    5.5 用户自编函数

    myfunction <- function (arg1, arg2, ...) {
        statements
        return(object)
    }
    

    5.6 整合与重构

    5.6.1 转置

    使用函数t()对一个矩阵或数据框进行转置。数据框行名将变成变量(列)名。

    > cars <- mtcars[1:5, 1:4]
    > cars
                       mpg cyl disp  hp
    Mazda RX4         21.0   6  160 110
    Mazda RX4 Wag     21.0   6  160 110
    Datsun 710        22.8   4  108  93
    Hornet 4 Drive    21.4   6  258 110
    Hornet Sportabout 18.7   8  360 175
    > t(cars)
         Mazda RX4 Mazda RX4 Wag Datsun 710 Hornet 4 Drive Hornet Sportabout
    mpg         21            21       22.8           21.4              18.7
    cyl          6             6        4.0            6.0               8.0
    disp       160           160      108.0          258.0             360.0
    hp         110           110       93.0          110.0             175.0
    

    5.6.2 整合数据

    使用一个或多个by变量和一个预先定义好的函数来折叠(collapse)数据。
    调用格式为:aggregate(x, by, FUN)
    其中x是待折叠的数据对象,by是一个变量名组成的列表,这些变量将被去掉以形成新的观测,而FUN则是用来计算描述性统计量的标量函数,他将被用来计算新观测中的值。

    > options(digits = 3)
    > attach(mtcars)
    > aggdata <- aggregate(mtcars, by = list(cyl, gear), FUN = mean, na.rm = TRUE)
    > aggdata
      Group.1 Group.2  mpg cyl disp  hp drat   wt qsec  vs   am gear carb
    1       4       3 21.5   4  120  97 3.70 2.46 20.0 1.0 0.00    3 1.00
    2       6       3 19.8   6  242 108 2.92 3.34 19.8 1.0 0.00    3 1.00
    3       8       3 15.1   8  358 194 3.12 4.10 17.1 0.0 0.00    3 3.08
    4       4       4 26.9   4  103  76 4.11 2.38 19.6 1.0 0.75    4 1.50
    5       6       4 19.8   6  164 116 3.91 3.09 17.7 0.5 0.50    4 4.00
    6       4       5 28.2   4  108 102 4.10 1.83 16.8 0.5 1.00    5 2.00
    7       6       5 19.7   6  145 175 3.62 2.77 15.5 0.0 1.00    5 6.00
    8       8       5 15.4   8  326 300 3.88 3.37 14.6 0.0 1.00    5 6.00
    

    5.6.3 reshape2 包

    reshape2包是一套重构和整合数据集的绝妙的万能工具。使用前需安装。

    1. 融合 P106
    2. 重铸 P106

    第6章 基本图形

    6.1 条形图

    barplot(height)
    其中的height是一个向量或一个矩阵。使用参数horiz = TRUE生成水平条形图。

    6.1.1 简单的条形图

    > library(grid)
    > library(vcd)
    > counts <- table(Arthritis$Improved)
    > counts
    
      None   Some Marked 
        42     14     28 
    > barplot(counts, main = "Simple Bar Plot", xlab = "Improvement", ylab = "Frequency")
    > barplot(counts, main = "Horizontal Bar Plot", xlab = "Frequency", ylab = "Improvement", horiz = TRUE)
    

    若要绘制的类别型变量是一个因子或有序型因子,可以用plot()快速创建垂直条形图,无需使用table()将其表格化:

    > plot(Arthritis$Improved, main = "Simple Bar Plot", xlab = "Improvement", ylab = "Frequency")
    > plot(Arthritis$Improved, main = "Horizontal Bar Plot", xlab = "Frequency", ylab = "Improvement", horiz = TRUE)
    

    6.1.2 堆砌条形图和分组条形图

    如果height是矩阵,绘图结果是堆砌条形图或分组条形图(beside = TRUE)。

    > barplot(counts, main = "Stacked Bar Plot", xlab = "Treatment", ylab = "Frequency", col = c("red", "yellow", "green"), legend = rownames(counts))
    > barplot(counts, main = "Grouped Bar Plot", xlab = "Treatment", ylab = "Frequency", col = c("red", "yellow", "green"), legend = rownames(counts), beside = TRUE)
    

    6.1.3 均值条形图

    可以使用数据整合函数将结果传递给barplot()函数,来创建表示均值、中位数、标准差等的条形图。

    > states <- data.frame(state.region, state.x77)
    > means <- aggregate(states$Illiteracy, by = list(state.region), FUN = mean)
    > means
            Group.1        x
    1     Northeast 1.000000
    2         South 1.737500
    3 North Central 0.700000
    4          West 1.023077
    > means <- means[order(means$x),]
    > means
            Group.1        x
    3 North Central 0.700000
    1     Northeast 1.000000
    4          West 1.023077
    2         South 1.737500
    > barplot(means$x, names.arg = means$Group.1)
    > title("Mean Illiteracy Rate")
    

    6.1.4 条形图的微调

    #增加y边界的大小
    > par(mar = c(5, 8, 4, 2))
    #旋转条形的标签
    > par(las = 2)
    > counts <- table(Arthritis$Improved)
    #缩小字体大小,修改标签文本
    > barplot(counts, main = "Treatment Outcome", horiz = TRUE, cex.names = 0.8, names.arg = c("No Improvement", "Some Improvement", "Marked Improvement"))
    

    6.1.5 棘状图

    对堆砌条形图进行重缩放,每个条形的高度均为1,每一段的高度即表示比例。
    由vcd包中的函数spine()绘制。

    > par(mar = c(5, 8, 4, 2))
    > par(las = 2)
    > counts <- table(Arthritis$Improved)
    > barplot(counts, main = "Treatment Outcome", horiz = TRUE, cex.names = 0.8, names.arg = c("No Improvement", "Some Improvement", "Marked Improvement"))
    

    6.2 饼图

    更推荐使用条形图或点图,相对于面积人们对长度的判断更精确。
    pie(x, labels)
    其中x是一个非负数值向量,表示每个扇形的面积,labels则是表示各扇形标签的字符型向量。

    > par(mfrow = c(2, 2)) #四幅图形组合成一幅
    > slices <- c(10, 12, 4, 16, 8)
    > lbls <- c("US", "UK", "Australia", "Germany", "France")
    > pie(slices, labels = lbls, main = "Simple Pie Chart")
     
    > pct <- round(slices / sum(slices) * 100)
    > lbls2 <- paste(lbls, " ", pct, "%", sep = "")
    > pie(slices, labels = lbls2, col = rainbow(length(lbls2)), main = "Pie Chart with Percentages")
    
    > library(plotrix)
    > pie3D(slices, labels = lbls, explode = 0.1, main = "3D Pie Chart")
    
    > mytable <- table(state.region) #从表格创建饼图
    > lbls3 <- paste(names(mytable), "\n", mytable, sep = "")
    > pie(mytable, labels = lbls3, main = "Pie Chart from a Table\n (with sample sizes)")
    

    饼图难以比较值,扇形图提供了一种同时展示相对数量和相互差异的方法。
    plotrix中的包fan.plot()实现。

    > library(plotrix)
    > slices <- c(10, 12, 4, 16, 8)
    > lbls <- c("US", "UK", "Australia", "Germany", "France")
    > fan.plot(slices, labels = lbls, main = "Fan Plot")
    

    6.3 直方图

    直方图描述连续型变量的分布,通过在x轴上将值域分割为一定数量的组,在y轴上显示相应值的频数。
    hist(x)
    其中x是一个由数据值组成的数值向量。参数freq = FALSE表示根据概率密度而不是频数绘制图形。参数breaks用于控制组的数量。

    > par(mfrow = c(2, 2))
    > hist(mtcars$mpg)
    > mtcars$mpg
    #指定组数和颜色
    > hist(mtcars$mpg, breaks = 12, col = "red", xlab = "Miles Per Gallon", main = "Colored histogram with 12 bins")
    #添加轴须图
    > hist(mtcars$mpg, freq = FALSE, breaks = 12, col = "red", xlab = "Miles Per Gallon", main = "Histogram, rug plot, density curve")
    > rug(jitter(mtcars$mpg))
    > lines(density(mtcars$mpg), col = "blue", lwd = 2)
    #添加正态密度曲线和外框
    > x <- mtcars$mpg
    > h <- hist(x, breaks = 12, col = "red", xlab = "Miles Per Gallon", main = "Histogram with normal curve and box")
    > xfit <- seq(min(x), max(x), length = 40)
    > yfit <- dnorm(xfit, mean = mean(x), sd = sd(x))
    > yfit <- yfit * diff(h$mids[1:2] * length(x))
    > lines(xfit, yfit, col = "blue", lwd  = 2)
    > box()
    

    如果数据有许多结(相同的值),rug(jitter(mtcars$mpag, amount = 0.01)),向每个数据点添加一个小的随机值(一个±amount之间的均匀分布随机数),以避免重叠的点产生影响。

    6.4 核密度图

    核密度估计是用于估计随机变量概率密度函数的一种非参数方法。
    plot(density(x))
    其中的x是一个数值型向量。plot()函数会创建一幅新的图形,所以要向一幅已经存在的图形上叠加一条密度曲线,可以使用lines()函数(见上文)。

    > par(mfrow = c(2, 1))
    > d <- density(mtcars$mpg)
    > plot(d)
    > plot(d, main = "Kernel Dendity of Miles Per Gallon")
    > polygon(d, col = "red", border = "blue") #polygon()函数根据定点的x和y坐标绘制多边形
    > rug(mtcars$mpg, col = "brown")
    

    核密度图可用于比较组间差异,使用sm包中的sm.density.compare()函数可向图形叠加两组或更多的核密度图:sm.density.compare(x, factor)
    其中的x是一个数值型向量,factor是一个分组变量。

    > library(sm)
    > attach(mtcars)
    #创建分组因子
    > cyl.f <- factor(cyl, levels = c(4, 6, 8), labels = c("4 cylinder", "6 cylinder", "8 cylinder"))
    #绘制密度图
    > sm.density.compare(mpg, cyl, xlab = "Miles Per Gallon")
    > title(main = "MPG Distribution by Car Cylinders")
    #通过鼠标单击添加图例
    > colfill <- c(2:(1 + length(levels(cyl.f))))
    > legend(locator(1), levels(cyl.f), fill = colfill)
    > detach(mtcars)
    

    6.5 箱线图

    箱线图(盒须图)是一项用来可视化分布和组间差异的绝佳图形手段(更常用)。
    通过绘制连续型变量的五数总括,即最小值、下四分位数(第25百分位数)、中位数(第50百分位数)、上四分位数(第75百分位数)以及最大值,描述了连续型变量的分布。箱线图能够显示出可能为离群点(范围±1.5*IQR以外的值,IQR表示四分位距,即上四分位数与下四分位数的差值)的观测。

    > boxplot(mtcars$mpg, main = "Box plot", ylab = "Miles per Gallon")
    #输出用于构建图形的统计量
    > boxplot.stats(mtcars$mpg)
    

    6.5.1 使用并列箱线图进行跨组比较

    箱线图可以展示单个变量或分组变量。使用格式为:
    boxplot(formula, data = dataframe)
    其中的formula是一个公式,dataframe代表提供数据的数据框或列表。
    一个实例公式为y ~ A,这将为类别型变量A的每个值并列地生成数值型变量y的箱线图。公式y ~ A*B则将为类别型变量A和B所有水平的两两组合生成数值型变量y的箱线图。
    添加参数varwidth = TRUE将使箱线图的宽度与其样本大小的平方根成正比。参数horizontal = TRUE可以反转坐标轴的方向。

    > attach(mtcars)
    > boxplot(mpg ~ cyl, data = mtcars, main = "Car Mileage Data", xlab = "Number of Cylinders", ylab = "Miles Per Gallon")
    #添加notch = TRUE得到含凹槽的箱线图。
    > boxplot(mpg ~ cyl, data = mtcars, notch = TRUE, col = "red", main = "Car Mileage Data", xlab = "Number of Cylinders", ylab = "Miles Per Gallon")
    > detach(mtcars)
    

    两个交叉因子的箱线图:

    #创建汽缸数量的因子
    > mtcars$cyl.f <- factor(mtcars$cyl, levels = c(4, 6, 8), labels = c("4", "6", "8"))
    #创建变速箱类型的因子
    > mtcars$am.f <- factor(mtcars$am, levels = c(0, 1), labels = c("anto", "standard"))
    > boxplot(mpg ~ am.f * cyl.f, data = mtcars, varwidth = TRUE, col = c("gold", "darkgreen"), main = "MPG Distribution by Auto Type", xlab = "Auto Type", ylab = "Miles Per Gallon")
    

    6.5.2 小提琴图

    箱线图与核密度图的结合,使用vioplot包中的vioplot()函数绘制。
    vioplot(x1, x2, ... , names = , col = )
    其中x1, x2, ...表示要绘制的一个或多个数值向量(将为每个向量绘制一幅小提琴图),参数names是小提琴图中标签的字符向量,而col是一个为每幅小提琴图指定颜色的向量。

    > library(vioplot)
    > x1 <- mtcars$mpg[mtcars$cyl == 4]
    > x2 <- mtcars$mpg[mtcars$cyl == 6]
    > x3 <- mtcars$mpg[mtcars$cyl == 8]
    > vioplot(x1, x2, x3, names = c("4 cyl", "6 cyl", "8 cyl"), col = "gold")
    > title("Violin Plots of Miles Per Gallon", ylab = "Miles Per Gallon", xlab = "Number of Cylinders")
    

    6.6 点图

    点图绘制变量中的所有值,提供了一种在水平刻度上绘制大量有标签值的方法。
    dotchart(x, labels = )
    其中的x是一个数值向量,而labels则是由每个点的标签组成的向量。可以通过添加参数groups来选定一个因子,用以指定x中元素的分组方式。如果这样做,gcolor可以控制不同组标签的颜色,cex可以控制标签的大小。

    > dotchart(mtcars$mpg, labels = row.names(mtcars), cex = .7, main = "Gas Mileage for Car Models", xlab = "Miles Per Gallon")
    #分组、排序、着色后的点图
    > x <- mtcars[order(mtcars$mpg), ]
    > x$cyl <- factor(x$cyl)
    > x$color[x$cyl == 4] <- "red"
    > x$color[x$cyl == 6] <- "blue"
    > x$color[x$cyl == 8] <- "darkgreen"
    > dotchart(x$mpg, labels = row.names(x), cex = .7, groups = x$cyl)
    > dotchart(x$mpg, labels = row.names(x), cex = .7, groups = x$cyl, gcolor = "black", color = x$color, pch = 19, main = "Gas Mileage for Car Models\n grouped by cylinder", xlab = "Miles Per Gallon")
    

    点图有许多变种,Hmisc包提供了一个带有许多附加功能的点图函数dotchart2。

    第7章 基本统计分析

    7.1 描述性统计分析

    相关文章

      网友评论

        本文标题:《R语言实战》学习笔记

        本文链接:https://www.haomeiwen.com/subject/afpzkxtx.html