【r<-数据分析】使用dplyr(1):介绍与filter操作

该部分学习内容来自《R for Data Science》。

在对数据进行可视化之前我们往往需要进行数据转换以得到可视化所需要的数据内容与格式。这里我们使用dplyr包操作2013年纽约市的航班起飞数据集(2013)。

准备

这部分我们聚焦于如何使用dplyr包,除ggplot2的另一个tidyverse核心成员。我们将使用nyclights13数据包解释关键的概念并使用ggplot2帮助理解数据。

# 导入包
library(nycflights13) # 请确保在使用前已经安装好这些包
library(tidyverse)
## Loading tidyverse: ggplot2
## Loading tidyverse: tibble
## Loading tidyverse: tidyr
## Loading tidyverse: readr
## Loading tidyverse: purrr
## Loading tidyverse: dplyr
## Conflicts with tidy packages ----------------------------------------------
## filter(): dplyr, stats
## lag():    dplyr, stats

注意一下你导入tidyverse包时给出的冲突信息(Conflicts),它告诉你dplyr覆盖了R基础包中的函数。如果你想要在载入tidyverse包后仍然使用这些函数,你需要使用函数的全名stats::filter()和stats::lag()进行调用。

nycflights13

我们将使用nycflights13::flights来探索dplyr包基本的数据操作动词。该数据集包含2013年336,776次航班起飞数据,来自美国交通统计局。

flights
## # A tibble: 336,776 x 19
##     year month   day dep_t~ sched_~ dep_d~ arr_~ sched~ arr_d~ carr~ flig~
##                    
##  1  2013     1     1    517     515   2.00   830    819  11.0  UA     1545
##  2  2013     1     1    533     529   4.00   850    830  20.0  UA     1714
##  3  2013     1     1    542     540   2.00   923    850  33.0  AA     1141
##  4  2013     1     1    544     545  -1.00  1004   1022 -18.0  B6      725
##  5  2013     1     1    554     600  -6.00   812    837 -25.0  DL      461
##  6  2013     1     1    554     558  -4.00   740    728  12.0  UA     1696
##  7  2013     1     1    555     600  -5.00   913    854  19.0  B6      507
##  8  2013     1     1    557     600  -3.00   709    723 -14.0  EV     5708
##  9  2013     1     1    557     600  -3.00   838    846 - 8.00 B6       79
## 10  2013     1     1    558     600  -2.00   753    745   8.00 AA      301
## # ... with 336,766 more rows, and 8 more variables: tailnum , origin
## #   , dest , air_time , distance , hour , minute
## #   , time_hour 

与基本包显示的普通数据集输出不同,这里适配地显示了在一个屏幕前几行和所有的列(我们可以使用View(flights)在Rstudio中查看数据集的所有信息。输出显示不同的原因是这个数据集是一个TibbleTibbles都是数据框data.frame,但经过改良以便于更好(在tidyverse生态中)工作。现在我们不必纠结于这些差异,在后续内容中我们会进行学习。

你可能已经注意到每个列名下面有三到四个字母的缩写。它们描述了每个变量的类型:

  • int代表整数
  • dbl代表浮点数或者实数
  • chr代表字符向量或者字符串
  • dttm代表日期-时间

还有其他三种数据类型在本部分不会使用到,但后续我们会接触:

  • lgl代表逻辑向量,只含TRUEFALSE
  • fctr代表因子,R用它来代表含固定可能值的分类变量
  • date代表日期

dplyr基础

这部分我们学习5个关键的dplyr函数,它可以让我们解决遇到的大部分数据操作问题:

  • 根据值选择观察(记录),filter()
  • 对行重新排序,arrange()
  • 根据名字选择变量,select()
  • 根据已知的变量创建新的变量,mutate()
  • 将许多值塌缩为单个描述性汇总,summarize()

这些函数都可以通过group_by()衔接起来,该函数改变上述每个函数的作用域,从操作整个数据集到按组与组操作。这六个函数提供了数据操作语言的动词。

所有的动词工作都非常相似:

  1. 第一个参数都是数据框
  2. 随后的参数描述了使用变量名(不加引号)对数据框做什么
  3. 结果是一个新的数据框

这些属性一起便利地将多个简单步骤串联起来得到一个复杂的操作(结果)。让我们实际来看看这些动词是怎么工作的。

使用filter()过滤行

filter()允许我们根据观测值来对数据集取子集。第一个参数是数据框的名字,第二和随后的参数是用于过滤数据框的表达式。

比如,我们可以选择所有一月一号的航班:

filter(flights, month == 1, day == 1)
## # A tibble: 842 x 19
##     year month   day dep_t~ sched_~ dep_d~ arr_~ sched~ arr_d~ carr~ flig~
##                    
##  1  2013     1     1    517     515   2.00   830    819  11.0  UA     1545
##  2  2013     1     1    533     529   4.00   850    830  20.0  UA     1714
##  3  2013     1     1    542     540   2.00   923    850  33.0  AA     1141
##  4  2013     1     1    544     545  -1.00  1004   1022 -18.0  B6      725
##  5  2013     1     1    554     600  -6.00   812    837 -25.0  DL      461
##  6  2013     1     1    554     558  -4.00   740    728  12.0  UA     1696
##  7  2013     1     1    555     600  -5.00   913    854  19.0  B6      507
##  8  2013     1     1    557     600  -3.00   709    723 -14.0  EV     5708
##  9  2013     1     1    557     600  -3.00   838    846 - 8.00 B6       79
## 10  2013     1     1    558     600  -2.00   753    745   8.00 AA      301
## # ... with 832 more rows, and 8 more variables: tailnum , origin
## #   , dest , air_time , distance , hour , minute
## #   , time_hour 

这一行代码dplyr执行了过滤操作并返回了一个新的数据框。dplyr从不修改输入数据,所以如果你想要保存数据,必须使用<-进行赋值

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

R要么输出结果,要么将结果保存到一个变量。如果我们想要同时做到这一点,你可以把赋值放在括号里:

(dec25 <- filter(flights, month == 12, day == 25))
## # A tibble: 719 x 19
##     year month   day dep_t~ sched_~ dep_d~ arr_~ sched~ arr_d~ carr~ flig~
##                    
##  1  2013    12    25    456     500  -4.00   649    651 - 2.00 US     1895
##  2  2013    12    25    524     515   9.00   805    814 - 9.00 UA     1016
##  3  2013    12    25    542     540   2.00   832    850 -18.0  AA     2243
##  4  2013    12    25    546     550  -4.00  1022   1027 - 5.00 B6      939
##  5  2013    12    25    556     600  -4.00   730    745 -15.0  AA      301
##  6  2013    12    25    557     600  -3.00   743    752 - 9.00 DL      731
##  7  2013    12    25    557     600  -3.00   818    831 -13.0  DL      904
##  8  2013    12    25    559     600  -1.00   855    856 - 1.00 B6      371
##  9  2013    12    25    559     600  -1.00   849    855 - 6.00 B6      605
## 10  2013    12    25    600     600   0      850    846   4.00 B6      583
## # ... with 709 more rows, and 8 more variables: tailnum , origin
## #   , dest , air_time , distance , hour , minute
## #   , time_hour 

比较

想要有效地过滤,你必须知道怎么利用比较操作符来选择观测值。R提供了标准的比较符:>,>=,<=,!===

如果你是初学R,一个常见的错误是用=而不是==来检测相等。如果这种情况发生了,你会收到报错信息:

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

另一个你在使用==时可能遭遇的常见问题是浮点数。下面的结果可能会让你惊掉大牙:

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

逻辑操作符

&是与,|是或,!是非。

下面代码找到在十一月或十二月起飞的所有航班:

filter(flights, month == 11 | month == 12)
## # A tibble: 55,403 x 19
##     year month   day dep_t~ sched~ dep_del~ arr_~ sche~ arr_d~ carr~ flig~
##                    
##  1  2013    11     1      5   2359     6.00   352   345   7.00 B6      745
##  2  2013    11     1     35   2250   105      123  2356  87.0  B6     1816
##  3  2013    11     1    455    500  -  5.00   641   651 -10.0  US     1895
##  4  2013    11     1    539    545  -  6.00   856   827  29.0  UA     1714
##  5  2013    11     1    542    545  -  3.00   831   855 -24.0  AA     2243
##  6  2013    11     1    549    600  - 11.0    912   923 -11.0  UA      303
##  7  2013    11     1    550    600  - 10.0    705   659   6.00 US     2167
##  8  2013    11     1    554    600  -  6.00   659   701 - 2.00 US     2134
##  9  2013    11     1    554    600  -  6.00   826   827 - 1.00 DL      563
## 10  2013    11     1    554    600  -  6.00   749   751 - 2.00 DL      731
## # ... with 55,393 more rows, and 8 more variables: tailnum , origin
## #   , dest , air_time , distance , hour , minute
## #   , time_hour 

注意,你不能写成filter(flights, month == 11 | 12),(虽然语义上讲的通)对于R而言,它会先计算11|12得到1,然后计算month == 1,这就不是我们需要的了!

解决这种问题的一种有用简写为x %in% y。这将选择符合x属于y的行(xy中的一个值)。我们可以用它重写前面的代码:

nov_dec <- filter(flights, month %in% c(11, 12))

缺失值

NA代表未知值或者称为缺失值,它是能“传染”的,几乎任何涉及未知值的操作都会是一个未知值。

NA > 5
## [1] NA
10 == NA
## [1] NA
NA + 10
## [1] NA
NA / 2
## [1] NA

最让人困惑的结果是这个:

NA == NA
## [1] NA

最简单理解为什么这是TRUE的方式是带入一点语境:

# 把x看作小明的年龄,我们不知道他多大
x <- NA

# 把y看作小红的年龄,我们不知道她多大
y <- NA

# 小明和小红一样大吗?
x == y
## [1] NA

# 我们不知道

如果你想确定一个值是不是缺失了,使用is.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.00
filter(df, is.na(x) | x > 1)
## # A tibble: 2 x 1
##       x
##   
## 1 NA   
## 2  3.00

练习

  1. 寻找满足以下条件的所有航班:
    • 有一次大于等于2小时的航班抵达延误
    • 飞去Houston(IAH或者HOU)
    • 航空公司为United,American或者Delta (应当缩写是UA和DL)
    • 在夏天起飞(July,August和September)
    • 抵达延误超过两小时,但起飞时间正常
    • 起飞时间在午夜到6.a.m之间(包含)
  2. 另一个有用的dplyr过滤助手是between()函数。它是做什么的?你可以使用它简化用于解决前面问题的代码吗?
  3. 有多少航班有一个缺失的dep_time?其他缺失的变量有哪些?这些行表示什么呢?
  4. 为什么NA ^ 0不是缺失值?为什么NA | TRUE不是缺失值?为什么FALSE & NA不是缺失值?你可以弄懂它们的基本原理吗?

练习有关的见解和答案我只发布在博客上(有兴趣学习还是要自己动手和思考下)

【r<-数据分析】使用dplyr(1):介绍与filter操作_第1张图片

你可能感兴趣的:(【r<-数据分析】使用dplyr(1):介绍与filter操作)