数据清洗之dplyr

作者: 土豆学生信 | 来源:发表于2019-06-22 17:04 被阅读16次

    本文来源于陈兴栋、张铁军、刘振球老师编写的《R语言与数据清洗》第九章数据汇总操作的学习笔记。dplyr包由Hadley Wickham创建,dplyr提供灵活的数据操作语法,专注于处理数据框的工具。要了解有关dplyr的更多信息,请从vignettes开始:

    browseVignettes(package =“dplyr”)
    

    dplyr包主要功能:

    1. 筛选各种变量select()
    2. 根据一个或者多个变量进行排序arrange()
    3. 变量重命名以及增加新的变量names()或者colnames()&mutate()
    4. 根据某个变量进行分类汇总summarize()
    5. 简单随机抽样sample()
    6. 各种连接inner_join()等
    7. 按行或者按列进行合并rbind()或者cbind()

    1. tbl_df函数

    过长过大的数据集显示为友好的表模式展现。

    首先要安装并载入这个dplyr包
    library(dplyr) 
    #查看mtcars的数据类型 
    class(mtcars)
    mtcars_df<- tbl_df(mtcars)
    

    2.filter函数

    与subset类似,按照逻辑条件筛选子集,支持任意条件组合,用“&”连接。

    #查看数据集mtcars_df的结构(有哪些变量,每个变量的类型等等)
    str(mtcars_df) 
    
    unique(mtcars_df$gear)
    
    #过滤出gear == 4的行
    filter(mtcars_df, gear == 4)
    
    #过滤出drat<3的行
    filter(mtcars_df, drat<3)
    
    #过滤出cyl < 6 并且 gear == 4的行
    filter(mtcars_df, cyl < 6 & gear == 4)
    
    #如下命令也能得到相同的结果
    filter(mtcars_df, cyl < 6, gear == 4)
    
    #过滤出cyl== 6或者carb > 5的行
    filter(mtcars_df, cyl== 6 |carb > 5)
    
    #过滤出carb为2或4的行
    filter(mtcars_df, carb %in% c(2, 4))
    
    #过滤出carb为2或4的行
    filter(mtcars_df, carb %in% c(2, 4))
    
    #选取第3行数据。注意3L是长型数值的写法。
    slice(mtcars_df, 3L)
    
    #或者使用filter函数,也能达到同样的目的:
    filter(mtcars_df, row_number() == 3L)
    
    #选取第3行数据。注意3L是长型数值的写法。
    slice(mtcars_df, 3L)
    
    #或者使用filter函数,也能达到同样的目的:
    filter(mtcars_df, row_number() == 3L)
    

    3. slice函数

    用于选出特定的几行数据,类似于“数据切片”

    #选取最后一行数据
    slice(mtcars_df, n())
    
    #选取第1行到第10行所有的数据,也可以使用slice函数或者filter函数:
    slice(mtcars_df, 1:10)
    filter(mtcars_df, between(row_number(), 1,10))
    

    4. arrange函数

    按照给定的列,对行进行排序。默认升序,对列名加desc()函数可以实现降序排序。原数据集行名称会被过滤掉。

    #以变量qsec按升序排序(从小到大排序)
    arrange(mtcars_df,qsec)
    
    #以变量qsec按降序(从大到小)排序
    arrange(mtcars_df, desc(qsec))
    
    #以qsec和disp联合升序排序。也就是说:首先按照qsec的升序(从小到大)排序;如果在qsec相等的情形下,则按照disp从小到大排序。
    arrange(mtcars_df, qsec, disp)
    
    #首先按照qsec的升序(从小到大)排序;如果在qsec相等的情形下,则按照disp的降序(从大到小)排序。
    arrange(mtcars_df, qsec, desc(disp))
    

    5. select()函数

    根据传入的列名选择子数据集。

    #选出mtcars这个数据集的cyl,gear,carb 这三列数据
    select(mtcars_df,cyl,gear,carb)
    
    #“:”使用冒号连接列名,选择多个列。例如选出mtcars这个数据集中从 hp这一列到 vs这一列之间的所有列数据
    select(mtcars_df,hp:vs)
    
    # “-” 用来删除不要的列数据。例如,删除数据集中从 hp这一列到 vs这一列之间的所有列数据,返回剩余的数据集。
    select(mtcars_df,-(hp:vs))
    
    iris_df <- tbl_df(iris)
    str(iris_df)
    
    #选取变量名前缀包含Sepal的列
    select(iris_df, starts_with("Sepal"))
    #结果会返回 Sepal.Length 和Sepal.Width这两列的值
    #选取变量名前缀不包含Sepal的列
    select(iris_df, -starts_with("Sepal"))
    #结果会返回 Petal.Length、 Petal.Width 和 Species这三列的值
    
    #选取变量名后缀包含Length的列
    select(iris_df, ends_with("Length"))
    #结果会返回 Sepal.Length和 Petal.Length这两列的值
    
    #选取变量名中包含eta的列
    select(iris_df, contains("eta"))
    #结果会返回 Petal.Length 和 Petal.Width这两列值
    
    #选取变量名中不包含eta的列
    select(iris_df, -contains("eta"))
    #结果会返回 Sepal.Length、Sepal.Width 和 Species这三列值
    
    #正则表达式匹配,返回变量名中包含t的列
    select(iris_df, matches(".t."))
    #返回Sepal.Length、Sepal.Width、Petal.Length和 Petal.Width这四列值
    
    # 使用one_of函数选择字符向量中的列,下面两个函数的结果是一致的
    select(iris_df, one_of(c("Sepal.Length", "Sepal.Width")))
    select(iris_df,Sepal.Length,Sepal.Width)
    #返回Sepal.Length和Sepal.Width这两列值
    
    #返回所有列,一般调整数据集中变量顺序时使用
    select(iris_df, everything())
    
    #调整列顺序,把Species列放到最前面,作为第一列
    select(iris_df, Species, everything())
    
    #重命名列Species,返回的子数据集只包含重命名的spec列
    select(iris_df, spec = Species)
    
    #将列Species重命名为spec,并返回全部列
    rename(iris_df, spec = Species)
    

    6. mutate函数

    对于数据集中的列进行运算,并添加到数据集中。原数据集行名称会被过滤掉。transmute()函数作用与之类似,但是只返回新变量。

    #计算新列wt_kg和wt_t,并添加新列到原数据集中(最后两列)
    mutate(mtcars_df, wt_kg = wt * 453.592, wt_t = wt_kg / 1000)
    
    #计算新列wt_kg和wt_t,返回对象中只包含新列
    transmute(mtcars_df, wt_kg = wt * 453.592, wt_t = wt_kg / 1000)
    

    7. distinct函数

    用于对数据集去重,返回无重复的行,类似于unique(),但是速度更快。原数据集行名称会被过滤掉。

    #设置随机数种子
    set.seed(1) 
    #构建一个简单的数据集
    df <- data.frame(x = sample(3,10, rep = TRUE), y = sample(c(2,3,4),10, rep = TRUE))
    df
    
    #以两个变量作为去重标准,即x和y均相同的观测会被剔掉重复的,只保留一个,返回去重后的数据。下面两个函数返回的结果是一致的:
    distinct(df) 
    distinct(df, x, y) 
    
    #以变量x去重,只返回去重后的x值
    distinct(df, x)
    
    #以变量x去重,并返回所有变量
    distinct(df, x, .keep_all = TRUE)
    
    #对变量运算后的结果去重 
    distinct(df, multi=x*y)
    

    8. summarize函数

    对数据框调用函数进行汇总操作。

    #返回数据框中变量wt的最大值及最小值
    summarise(mtcars_df, max(wt), min(wt))
    

    9.sample()函数

    sample函数可以完成随机抽样处理
    size 抽取样本的数目
    replace 如果为F(默认),则是不重复抽样,此时size不能大于x的长度;
    如果为T,则是重复抽样,此时size允许大于x的长度

    #sample_n函数的例子
    set.seed(1)
    
    #随机无重复的取15行数据
    sample_n(mtcars_df,15)
    
    #随机有重复的取100行数据
    sample_n(mtcars_df, 100, replace = TRUE)
    
    #随机无重复的以 qsec值做权重抽取5行数据。如果某一行数据其对应的qsec值越大,那这一行数据被抽中的可能性也会越大
    sample_n(mtcars_df, 5, weight =  qsec)
    
    #sample_frac函数的例子
    set.seed(1)
    
    #默认size=1,相当于对全部数据无重复重新抽样
    sample_frac(mtcars)
    
    #随机无重复的取30%的数据
    sample_frac(mtcars_df, 0.3) 
    
    #随机有重复的取总行数1.2倍的数据
    sample_frac(mtcars_df, 1.2, replace = TRUE)
    
    #随机无重复的以1/qsec值做权重取30%的数据
    sample_frac(mtcars_df, 0.3, weight = 1/qsec)
    

    10. group_by()函数

    用于对数据集按照给定变量分组,返回分组后的数据集。

    #使用变量gear对mtcars分组,返回分组后数据集。但是此时的by_gear数据集的结构与原始的mtcars_df相同。
    by_gear <- group_by(mtcars_df, gear)
    
    #返回每个分组中最大qsec所在的行
    filter(by_gear, qsec == max(qsec))
    
    #返回每个分组中变量名包含d的列,始终返回分组列gear
    select(by_gear, contains("d"))
    
    #使用qsec对每个分组排序
    arrange(by_gear,  qsec)
    
    #对每个分组无重复的取3行记录
    sample_n(by_gear, 3)
    
    #返回每个分组的记录数
    summarise(by_gear, n())
    
    #求每个分组中disp和hp的均值
    summarise(by_gear, mean(disp), mean(hp))
    
    #返回每个分组中disp第二个值(不是第二大的值)
    summarise(by_gear, nth(disp,2))
    
    #获取分组数据集所使用的分组变量
    groups(by_gear)
    
    #ungroup从数据框中移除组合信息(因此返回的分组变量为NULL) 
    groups(ungroup(by_gear)) 
    
    group_indices(mtcars_df, gear)
    by_gear <- group_by(mtcars_df, gear)
    
    #返回每个分组中的样本记录数。下面三个函数都能达到同样的目的:
    group_size(by_gear)
    summarise(by_gear, n())
    table(mtcars$gear)
    
    #返回所分的组数
    n_groups(by_gear)
    length(group_size(by_gear))
    
    #使用count对分组计数,数据已按变量分组
    count(mtcars_df,gear)
    
    #使用tally对分组计数,需要使用group_by分组
    by_gear <- group_by(mtcars_df, gear)
    tally(by_gear) 
    
    #按gear分组,并对分组数据计算变量的mpg的和
    count(mtcars_df,gear, wt = mpg)
    
    tally(by_gear, wt = mpg)
    

    11. %>%连接符

    “%>%”这个管道函数把左件的值发送给右件的表达式,并作为右件表达式函数的第一个参数。

    result <- flights %>%
      #将flights数据集传给下面的group_by函数
      group_by(year, month, day) %>%
      select(arr_delay, dep_delay) %>%
      summarise(
        arr = mean(arr_delay, na.rm = TRUE),
        dep = mean(dep_delay, na.rm = TRUE)
      ) %>%
      filter(arr > 30 | dep > 30)
    head(result)
    
    a1 <- group_by(flights, year, month, day)
    a2 <- select(a1, arr_delay, dep_delay)
    a3 <- summarise(a2,
                    arr = mean(arr_delay, na.rm = TRUE),
                    dep = mean(dep_delay, na.rm = TRUE))
    a4 <- filter(a3, arr > 30 | dep > 30)
    

    管道函数还可以用在自定义函数(function)中,比如我们定义一个对向量中的数求整后取绝对值求和的函数。

    ## 一般代码:
    
    f1=function(x)sum(abs(round(x)))
    
    ## 管道函数代码
    
    f2=.%>% round %>% abs %>% sum
    

    %<>% 在%>%的基础上,会把右件的最终返回值返回给左件(注意是最终)。
    a %in% table
    a值是否包含于table中,为真输出TURE,否者输出FALSE。

    参考:

    1. 陈兴栋、张铁军、刘振球老师《R语言与数据清洗》
    2. Introduction to dplyr
    3. https://dplyr.tidyverse.org/
    4. R语言数据处理利器——dplyr简介

    相关文章

      网友评论

        本文标题:数据清洗之dplyr

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