1 dplyr: Data transformation
dplyr 承担了 tidyverse 中最基本也最重要的数据处理、转换、分析功能(to my mind)。它的设计思想是发展处一套简洁、统一的数据操作语法(a grammar of data manipulation),用英语中常见的动词命名操作数据的函数,并充分利用管道符 %>%
和更“现代”的数据框格式 tibble
增加代码可读性。
为了介绍 dplyr 中的基本数据操作。可以使用 nycflights::flights
,这个数据集包含了 2013 年从纽约市处罚的所有 336776 次航班的信息。该数据来自于美国交通统计局。
library(nycflights13)
flights
#> # A tibble: 336,776 x 19
#> year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
#> <int> <int> <int> <int> <int> <dbl> <int> <int>
#> 1 2013 1 1 517 515 2 830 819
#> 2 2013 1 1 533 529 4 850 830
#> 3 2013 1 1 542 540 2 923 850
#> 4 2013 1 1 544 545 -1 1004 1022
#> 5 2013 1 1 554 600 -6 812 837
#> 6 2013 1 1 554 558 -4 740 728
#> # ... with 336,770 more rows, and 11 more variables: arr_delay <dbl>,
#> # carrier <chr>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
#> # air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>
专门为 tibble
数据格式编写的函数 glimpse()
,它的功能和 str()
类似,但输出更为整洁,显示的数据也更多一些:
glimpse(flights)
#> Rows: 336,776
#> Columns: 19
#> $ year <int> 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013...
#> $ month <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1...
#> $ day <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1...
#> $ dep_time <int> 517, 533, 542, 544, 554, 554, 555, 557, 557, 558, 55...
#> $ sched_dep_time <int> 515, 529, 540, 545, 600, 558, 600, 600, 600, 600, 60...
#> $ dep_delay <dbl> 2, 4, 2, -1, -6, -4, -5, -3, -3, -2, -2, -2, -2, -2,...
#> $ arr_time <int> 830, 850, 923, 1004, 812, 740, 913, 709, 838, 753, 8...
#> $ sched_arr_time <int> 819, 830, 850, 1022, 837, 728, 854, 723, 846, 745, 8...
#> $ arr_delay <dbl> 11, 20, 33, -18, -25, 12, 19, -14, -8, 8, -2, -3, 7,...
#> $ carrier <chr> "UA", "UA", "AA", "B6", "DL", "UA", "B6", "EV", "B6"...
#> $ flight <int> 1545, 1714, 1141, 725, 461, 1696, 507, 5708, 79, 301...
#> $ tailnum <chr> "N14228", "N24211", "N619AA", "N804JB", "N668DN", "N...
#> $ origin <chr> "EWR", "LGA", "JFK", "JFK", "LGA", "EWR", "EWR", "LG...
#> $ dest <chr> "IAH", "IAH", "MIA", "BQN", "ATL", "ORD", "FLL", "IA...
#> $ air_time <dbl> 227, 227, 160, 183, 116, 150, 158, 53, 140, 138, 149...
#> $ distance <dbl> 1400, 1416, 1089, 1576, 762, 719, 1065, 229, 944, 73...
#> $ hour <dbl> 5, 5, 5, 5, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6...
#> $ minute <dbl> 15, 29, 40, 45, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59...
#> $ time_hour <dttm> 2013-01-01 05:00:00, 2013-01-01 05:00:00, 2013-01-0...
str(flights)
#> tibble [336,776 x 19] (S3: tbl_df/tbl/data.frame)
#> $ year : int [1:336776] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
#> $ month : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
#> $ day : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
#> $ dep_time : int [1:336776] 517 533 542 544 554 554 555 557 557 558 ...
#> $ sched_dep_time: int [1:336776] 515 529 540 545 600 558 600 600 600 600 ...
#> $ dep_delay : num [1:336776] 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
#> $ arr_time : int [1:336776] 830 850 923 1004 812 740 913 709 838 753 ...
#> $ sched_arr_time: int [1:336776] 819 830 850 1022 837 728 854 723 846 745 ...
#> $ arr_delay : num [1:336776] 11 20 33 -18 -25 12 19 -14 -8 8 ...
#> $ carrier : chr [1:336776] "UA" "UA" "AA" "B6" ...
#> $ flight : int [1:336776] 1545 1714 1141 725 461 1696 507 5708 79 301 ...
#> $ tailnum : chr [1:336776] "N14228" "N24211" "N619AA" "N804JB" ...
#> $ origin : chr [1:336776] "EWR" "LGA" "JFK" "JFK" ...
#> $ dest : chr [1:336776] "IAH" "IAH" "MIA" "BQN" ...
#> $ air_time : num [1:336776] 227 227 160 183 116 150 158 53 140 138 ...
#> $ distance : num [1:336776] 1400 1416 1089 1576 762 ...
#> $ hour : num [1:336776] 5 5 5 5 6 5 6 6 6 6 ...
#> $ minute : num [1:336776] 15 29 40 45 0 58 0 0 0 0 ...
#> $ time_hour : POSIXct[1:336776], format: "2013-01-01 05:00:00" "2013-01-01 05:00:00" ...
五个 dplyr
核心函数能解决数据转换中的绝大多数问题:
- 使用
filter()
筛选行
- 使用
arrange()
排列行
- 使用
select
选取列
- 用现有的变量创建新变量
mutate()
- 聚合并计算摘要统计量
summarize()
上面的所有函数都可以和 group_by()
函数联合起来使用,group_by()
函数可以改变以上每个函数的作用范围,让其从在整个数据集上操作变为在每个变量的水平上分别操作。这 6 个函数构成了数据处理的基本工具。
这些函数有完全相同的参数结构和工作方式:
- 第一个参数是数据集,表明我们想对什么数据进行处理
- 随后的参数是变量名称(不带引号)描述了在数据上进行什么处理,不同的变量之间用逗号分隔
- 它们不会改变原数据,而是生成一个新的数据框