【R语言与数据分析实战】数据操作(一):基于向量的处理与外部数据处理

目录

  • 1、R中的常用数据集
  • 2、读写CSV文件
    •   (1) 读写CSV文件
    •   (2) 读写对象文件
  • 3、合并数据框的行与列
  • 4、apply系数函数
    •   (1) apply
    •   (2) lapply
    •   (3) sapply
    •   (4) tapply

1、R中的常用数据集

数据集 含义
AirPassenger Box &Jenkins航空公司1949年~1960年每月国际航线乘客数
airquality 纽约市1973年5月~9月每日空气质量
cars 20世纪20年代汽车速度对刹车距离的影响
mtcars 1974年美国Motor Trend杂志上刊登的32辆车的11个指标数据
Titanic “泰坦尼克”号生还者信息,包括舱室(一等舱、二等舱、三等舱)、性别、年龄、是否生还
InsectSprays 使用6种杀虫剂后各自的害虫存活率
Orange 橙树的种类、树龄、树围
SWiSS 1888年前后,瑞士联邦47个法语州的生育率与社会经济指标(农业从业者比例、入伍考试成绩、教育等)

2、读写CSV文件

  (1) 读写CSV文件

read.csv(   #将csv文件读入数据框
    file,   #文件名
    header=FALSE, # 是否指定文件第一行为标题
    
    #数据中含有缺失值时,指定与R的NA相对应的值。
    #默认值为"NA”,保存为"NA的字符串会被保存为R中的NA。
    na.strings="NA",
    
    #用于指定将字符串保存为因子还是字符串。
    #若不设置,则采用默认值TRUE,即转换成因子。
    stringsAsFactors=default.stringsAsFactors()
)   #返回值为数据框。

write.csv(   #将数据框保存为CSv文件
    X,   #要保存在文件中的数据框或矩阵
    file="",  #保存数据的文件名
    row.names=TRUE  #若为TRUE,则将行名也保存到csV文件。
)

        有时,数据中可能含有表示NA的字符串,在使用read.csv()函数读入这些数据时,会被转换为因子,这会导致整个列都被转换为因子。此时,使用na.strings参数可以避免这一问题。na.strings参数的默认值为NA,这意味着数据中的NA字符串会被转换为R能够识别的NA值。

  (2) 读写对象文件

        R中有save()、load()两个函数,使用它们可以将R对象保存到二进制文件,也可以从二进制文件中读取R对象。

save(   #将内存中的对象保存到文件,      #要保存的对象名
    list=character(), #将要保存的对象名设置为向量时,用于代替···
    file    #文件名# 例如
save(list=ls(),file="abc.RData") #将内存中所有的对象保存在指定文件中
load(    #将对象从指定文件读入内存
    file    #文件名
)  #返回值为保存对象名称的向量,这些对象是从文件读入的

3、合并数据框的行与列

函数 含义
rbind(…) 按行合并指定数据
cbind(…) 按列合并指定数据
# 例如
rbind(c(1,2,3),c(4,5,6))

         [,1] [,2] [,3]
    [1,]   1   2   3
    [2,]   4   5   6

x <-data.frame(id=c(1,2),name=c("a","b"),stringsAsFactors=F) 
#设置stringsAsFactors=FALSE保证其不会被转换为因子
rbind(x,c(3,"c"))

        id  name
    1   1     a
    2   2     b
    3   3     c

cbind(c(1,2,3),c(4,5,6))

          [,1] [,2]
    [1,]   1   4
    [2,]   2   5
    [3,]   3   6

4、apply系数函数

函数 说明 特性
apply() 向数组或矩阵应用指定函数,然后将结果值以向量、数组或列表形式返回 适用于数组或矩阵
lapply() 向向量、列表或表达式应用函数,并以列表形式返回结果sapply() 与lapply()类似,但以向量、矩阵或数组形式返回结果 返回列表
tapply() 根据指定标准对向量中的数据分组,然后对每个分组应用指定函数,并返回结果 返回向量、矩阵或数组
mapply() sapply()函数的扩展版本,借助参数接收多个向量或列表,然后针对各数据的第一个元素应用函数计算结果,然后针对第二个元素,再针对第三个元素……以此类推,最后返回所有计算结果 将多个数据应用为函数参数

  (1) apply

        apply()函数按矩阵的行或列方向应用指定函数。

apply( #沿MARGIN方向,向数组或矩阵应用函数FUN,并以向量、数组或列表形式返回结果。
    X,     #数组或矩阵
    MARGIN,#应用函数的方向。1是沿行方向,2是沿列方向。
            #C(1,2)表示同时沿行与沿列方向。
    FUN     #要应用的函数
)   #FUN函数返回长度为1的向量时,返回向量;
    #返回大于1的向量时,返回矩阵;
    #返回长度不同的向量时,返回列表。
    
#例如:使用apply()函数对矩阵应用求和函数,计算矩阵中保存的数据之和。
d <- matrix(1:9,ncol=3)

        [,1]  [,2] [,3]
    [1,]    1   4   7
    [2,]    2   5   8
    [3,]    3   6   9

apply(d,1,sum)

    [1] 12 15 18

apply(d,2,sum)

    [1] 6 15 24
        R还专门定义了rowSums()、rowMeans()、colSums()、colMeans()函数,对行或列进行求和或均值计算。

  (2) lapply

        lapply()函数以列表形式返回应用函数的结果。

lapply(    #向列表、向量、表达式、数据框等应用指定函数,并将结果以列表形式返回。
    X,     #向量、列表、表达式或数据框
    FUN,   #待应用的函数#额外参数,这些参数会被传递给FUN函数。#返回值为与x等长的列表。

        从使用角度看,向量与数据框比列表更直观,所以有必要转换lapply()的结果。此时,可以使用下面所示的两个函数,将列表转换为其他数据类型。

unlist(  #将列表转换为向量。
    x,              #R对象,一般为列表或向量
    recursive=FALSE, #是否对x中的列表进行递归转换
    use.names=TRUE   #是否保留列表中的值名称
)   #返回向量
 
do.call(  #调用指定函数,将以列表形式给出的参数传递给被调用函数,返回函数调用结果。
    what,    #要调用的函数
    args,    #要传递给函数的参数列表
)    #返回值为函数调用结果

        下面通过lapply()函数对向量c(1,2,3)中的每个数进行“乘2”运算。

(result <- lapply(1:3,function(x) {x*2}))

    [[1]]
    [1] 2

    [[2]]
    [1] 4

    [[3]]
    [1] 6

unlist(result)

    [1] 2 4 6
        lapply()函数可以接收列表作为参数。例如,使用lapply()函数为列表中的每个变量计算平均值。

x <- list(a=1:3,b=4:6)
lapply(x,mean)

    $a
    [1] 2

    $b
    [1] 5
        使用lapply()函数处理数据框后得到列表,有时可能需要将得到的列表再次转换为数据框。转换处理需要经过如下几个阶段。

  • 使用unlist)函数,将列表转换为向量。
  • 使用matrix()函数,将向量转换为矩阵。
  • 使用as.data.frame(函数,将矩阵转换为数据框。
  • 使用names 函数,从列表获取变量名,赋给数据框的各列。

        下列示例中,先使用lapply)函数对鸢尾花数据集的前4列分别求平均值,然后将结果再次转换为数据框。

d <- as.data.frame(matrix(unlist(lapply(iris[, 1:4), mean)),ncol=4,byrow=TRUE))
names (d)<- names (iris [, 1:4])
d

      Sepal.Length  Sepal.Width  Petal.Length  Petal.Width
    1      5.843333      3.057333              3.758      1.199333
        此外,还可以使用do.call()函数进行类型转换。前面示例中,对鸢尾花数据集的前4列数据应用lapply()函数后,求出各列平均值,并存放到列表。接下来,可以使用cbind()函数将这些平均值合并为新数据框的列。下列代码中,使用do.call()函数,将lapply()函数返回的列表中的各元素作为参数传递给cbind()函数。

 data.frame(do.call(cbind, lapply(iris[, 1:4], mean)))

      Sepal.Length  Sepal.Width  Petal.Length  Petal.Width
    1      5.843333      3.057333              3.758      1.199333
        上述两种方法中,使用第一种方法(先使用unlist(函数将列表转换为向量,再使用matrix()函数将向量转换为矩阵时会有一个问题,那就是使用unlist()函数将列表转换为向量后,由于向量中只能保存1种数据类型,所以转换过程中,所有数据都会被转换为同一数据类型。当列表中同时存在字符串与数值时,使用unlist()函数将列表转换为向量后,所有字符串都被转换为莫名其妙的数值。 因此,列表中有不同数据类型的数据时,必须使用do.call()函数进行类型转换。

  (3) sapply

        sapply()函数与lapply()函数类似,但以矩阵、向量等数据类型返回结果。

sapply:向列表、向量、表达式、数据框等应用指定函数,然后以向量或矩阵形式返回结果。
sapply(
    X,      #向量、列表、表达式、数据框
    FUN,    #待应用的函数
    ···,    #额外参数,这些参数将传递给FUN函数。

        使用as.data.frame()函数可以将sapply()函数返回的向量进一步转换为数据框。此时,若不使用t(x)函数转置向量的行与列,将无法得到想要的数据框。下列示例中,先使用sapply()函数对鸢尾花数据集的前4列分别求平均值,得到包含平均值的向量后,再使用as.data.frame()函数将向量转换为数据框。

x <- sapply(iris[, 1:4], mean)
as.data.frame(x)

                                         X
    Sepal.Length   5.843333
    Sepal.Width     3.057333
    Petal.Length    3.758000
    Petal.Width      1.199333

as.data.frame(t(x))

      Sepal.Length  Sepal.Width  Petal.Length  Petal.Width
    1      5.843333      3.057333              3.758      1.199333
        处理包含多列的数据框时,常常需要判断各列的数据类型,比如判断某列中保存的数据是否为数值。此时,使用sapply()函数能够很方便地进行判断。下列示例中,使用sapply()函数判断鸢尾花数据集中各列的数据类型。

sapply(iris,class)

    Sepal.Length  Sepal.Width  Petal.Length  Petal.Width  Species
       “numeric”        “numeric”       “numeric”     “numeric”     “factor”
        向量或矩阵只能保存同种数据类型的数据,而sapply()函数返回的是向量或矩阵,因此,作为sapply()函数的参数传入的FUN函数返回值中,不能混有多种数据类型。若对各列应用函数后所得结果的数据类型彼此不同,此时应该使用返回列表的lapply()函数,或者plyr包中的相关函数。

  (4) tapply

        apply系列函数中,使用tapply()函数会先对数据进行分组,然后将函数应用到各组。

tapply( #根据给定的标准,对向量中保存的数据进行分组,然后对各分组应用指定函数,并返回结果。
    X,     #向量
    INDEX,  #数据分组索引。该参数应该被设置为因子,非因子的数据类型会被自动转换为因子。
    FUN,    #要向各分组应用的函数
    ···,    #额外参数,这些参数将被传递给FUN函数。
)    #返回值为数组。

        下列示例中,将1~10的10个数字全部划分到一个分组,对该分组中的所有数据求和,得到数据总和55。

tapply(1:10, rep(1, 10), sum)

     1
    55
        上述示例代码中,rep(1,10)表示将1重复10次。因此,数字1、2、3···10拥有相同的分组编号,分别为1、1、1…1,即它们都属于分组1,对分组1中的数据求和,得到55(=1+2+3+···+10)。
        接下来,将1~10的10个数字划分到偶数与奇数两个分组中,再对两个分组分别求和。在INDEX参数中使用x%%2=1作为分组标准,将10个数字分别划分到偶数组与奇数组。

tapply(1:10, 1:10 %% 2 == 1, sum)

    FALSE  TRUE
           30        25
        运行上述代码后,得到偶数和为30(=2+4+6+8+10)、奇数和等于25(=1+3+5+7+9)。






ps:文章用于学习

[参考书目] 徐珉久,R语言与数据分析实战,2017

你可能感兴趣的:(r语言,r语言,数据分析,开发语言)