[13] 《R数据科学》使用dplyr进行数据转换

一般来说,如果你需要创建一些新变量或者摘要统计量,并且对变量进行重命名或者对观测值进行重新排序,以便数据更容易处理,那么可以用dplyr包来转换数据,并创建一个新的数据集。

说实话dplyr是真的香,Y叔写过一篇比较awk和dplyr的文章,这也坚定了我要学好dplyr的信念。
忘记awk吧,dplyr它不香吗?

准备工作

library(nycflights13)
library(tidyverse)

nycflights13

为了介绍dplyr中的基本数据操作,我们需要使用nycflights13::flights。这个数据框包含了2013年从纽约市出发的所有336776次航班的信息。

flights
# A tibble: 336,776 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay
                                           
 1  2013     1     1      517            515         2      830            819        11
 2  2013     1     1      533            529         4      850            830        20
 3  2013     1     1      542            540         2      923            850        33
 4  2013     1     1      544            545        -1     1004           1022       -18
 5  2013     1     1      554            600        -6      812            837       -25
 6  2013     1     1      554            558        -4      740            728        12
 7  2013     1     1      555            600        -5      913            854        19
 8  2013     1     1      557            600        -3      709            723       -14
 9  2013     1     1      557            600        -3      838            846        -8
10  2013     1     1      558            600        -2      753            745         8
# ... with 336,766 more rows, and 10 more variables: carrier , flight ,
#   tailnum , origin , dest , air_time , distance , hour ,
#   minute , time_hour 

dplyr基础

5个dplyr核心函数:
按值筛选观测(filter()
对行进行重新排序(arrange()
按名称选取变量(select()
使用现有变量函数创建新变量(mutate()
将多个值总结为一个摘要统计量(summarize()

此外,这些函数都可以和group_by()函数联合起来用,group_by()函数可以改变以上每个函数的作用范围,让其从整个数据上的操作变为在每个分组上的操作。

使用filter()筛选行

筛选出1月1日的所有航班

filter(flights,month == 1,day == 1)
# A tibble: 842 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay
                                           
 1  2013     1     1      517            515         2      830            819        11
 2  2013     1     1      533            529         4      850            830        20
 3  2013     1     1      542            540         2      923            850        33
 4  2013     1     1      544            545        -1     1004           1022       -18
 5  2013     1     1      554            600        -6      812            837       -25
 6  2013     1     1      554            558        -4      740            728        12
 7  2013     1     1      555            600        -5      913            854        19
 8  2013     1     1      557            600        -3      709            723       -14
 9  2013     1     1      557            600        -3      838            846        -8
10  2013     1     1      558            600        -2      753            745         8
# ... with 832 more rows, and 10 more variables: carrier , flight ,
#   tailnum , origin , dest , air_time , distance , hour ,
#   minute , time_hour 

如果运行这行代码,dplyr就会执行筛选操作,并返回一个新的数据框。
如果你想要保存函数结果,那么你需要运用<-符号:

jan1 <- filter(flights,month == 1,day == 1)

如果你既想要输出结果,又想赋值,可以在两端加括号:

(dec25 <- filter(flights,month == 12,day == 25))
# A tibble: 719 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay
                                           
 1  2013    12    25      456            500        -4      649            651        -2
 2  2013    12    25      524            515         9      805            814        -9
 3  2013    12    25      542            540         2      832            850       -18
 4  2013    12    25      546            550        -4     1022           1027        -5
 5  2013    12    25      556            600        -4      730            745       -15
 6  2013    12    25      557            600        -3      743            752        -9
 7  2013    12    25      557            600        -3      818            831       -13
 8  2013    12    25      559            600        -1      855            856        -1
 9  2013    12    25      559            600        -1      849            855        -6
10  2013    12    25      600            600         0      850            846         4
# ... with 709 more rows, and 10 more variables: carrier , flight ,
#   tailnum , origin , dest , air_time , distance , hour ,
#   minute , time_hour 

比较运算符

R提供了一套标准的运算符号:>、>=、<、<=、!=(不等于)、==(等于)。
在R中 = 用 == 来代替,如果使用 = 会出现:

filter(flights,month=1)
#错误: `month` (`month = 1`) must not be named, do you need `==`?

介绍一个令人目瞪狗呆的操作:

sqrt(2)^2 == 2
#[1] FALSE
1/49 * 49 == 1
#[1] FALSE

根号2的平方等于2,以及1/49×49=1,返回的逻辑值都为FALSE,这个原因是计算机不会储存无限位的数,如果想让上面运行为TRUE,需要借助near()

near(sqrt(2)^2, 2)
#[1] TRUE
near(1/49 * 49, 1)
#[1] TRUE

逻辑运算符

简单来说,你可以叫它“与(&),或(|),非(!)”
举个例子,找出11月或12月出发的所有航班:

filter(flights,month == 11 | month == 12)
# A tibble: 55,403 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay
                                           
 1  2013    11     1        5           2359         6      352            345         7
 2  2013    11     1       35           2250       105      123           2356        87
 3  2013    11     1      455            500        -5      641            651       -10
 4  2013    11     1      539            545        -6      856            827        29
 5  2013    11     1      542            545        -3      831            855       -24
 6  2013    11     1      549            600       -11      912            923       -11
 7  2013    11     1      550            600       -10      705            659         6
 8  2013    11     1      554            600        -6      659            701        -2
 9  2013    11     1      554            600        -6      826            827        -1
10  2013    11     1      554            600        -6      749            751        -2
# ... with 55,393 more rows, and 10 more variables: carrier , flight ,
#   tailnum , origin , dest , air_time , distance , hour ,
#   minute , time_hour 

当然这个问题有一种简写的方式,利用x %in% y,这会选出x是y中一个值时的所有行:

filter(flights,month %in% c(11,12))
# A tibble: 55,403 x 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay
                                           
 1  2013    11     1        5           2359         6      352            345         7
 2  2013    11     1       35           2250       105      123           2356        87
 3  2013    11     1      455            500        -5      641            651       -10
 4  2013    11     1      539            545        -6      856            827        29
 5  2013    11     1      542            545        -3      831            855       -24
 6  2013    11     1      549            600       -11      912            923       -11
 7  2013    11     1      550            600       -10      705            659         6
 8  2013    11     1      554            600        -6      659            701        -2
 9  2013    11     1      554            600        -6      826            827        -1
10  2013    11     1      554            600        -6      749            751        -2
# ... with 55,393 more rows, and 10 more variables: carrier , flight ,
#   tailnum , origin , dest , air_time , distance , hour ,
#   minute , time_hour 

有时也可以用德摩根定律对复杂的筛选条件进行简化:!(x&y)等价于!x | !y,!(x | y)等价于!x&!y。例如,筛选出延误时间(到达或出发)不多于2小时的航班:

filter(flights, arr_delay <= 120,dep_delay <= 120)
filter(flights, !(arr_delay > 120|dep_delay > 120))

两种方式都可以实现筛选效果。

缺失值

缺失值我们通常用NA(not available,不可用)表示。
如果想要确定一个值是否为缺失值,可以使用is.na(x)函数:

x <- NA
is.na(x)
#[1] TRUE

filter()只能筛选出条件为TRUE的行,会排除条件为FALSE和NA的行。如果要保留缺失值,可以明确指出:

df <- tibble(x = c(1,NA,3))
filter(df,x>1)
# A tibble: 1 x 1
      x
  
1     3
filter(df,is.na(x)|x>1)
# A tibble: 2 x 1
      x
  
1    NA
2     3

你可能感兴趣的:([13] 《R数据科学》使用dplyr进行数据转换)