专栏首页庄闪闪的R语言手册R数据科学|3.7内容介绍及习题解答

R数据科学|3.7内容介绍及习题解答

3.7 分组新变量(和筛选器)

虽然与summarize()函数结合起来使用是最有效的,但分组也可以与mutate()filter()函数结合,以完成非常便捷的操作。示例如下:

  • 找出每个分组中最差的成员:
flights_sml %>%
 group_by(year, month, day) %>%
 filter(rank(desc(arr_delay)) < 10)
#> Source: local data frame [3,306 x 7]
#> Groups: year, month, day [365]
#>
#> year month day dep_delay arr_delay distance
#> <int> <int> <int> <dbl> <dbl> <dbl>
#> 1 2013 1 1 853 851 184
#> 2 2013 1 1 290 338 1134
#> 3 2013 1 1 260 263 266
#> 4 2013 1 1 157 174 213
#> 5 2013 1 1 216 222 708
#> 6 2013 1 1 255 250 589
#> # ... with 3,300 more rows, and 1 more variables:
#> # air_time <dbl>
  • 找出大于某个阈值的所有分组:
popular_dests <- flights %>%
 group_by(dest) %>%
 filter(n() > 365)
popular_dests
#> Source: local data frame [332,577 x 19]
#> Groups: dest [77]
#>
#> year month day dep_time sched_dep_time dep_delay
#> <int> <int> <int> <int> <int> <dbl>
#> 1 2013 1 1 517 515 2
#> 2 2013 1 1 533 529 4
#> 3 2013 1 1 542 540 2
#> 4 2013 1 1 544 545 -1
#> 5 2013 1 1 554 600 -6
#> 6 2013 1 1 554 558 -4
#> # ... with 3.326e+05 more rows, and 13 more variables:
#> # arr_time <int>, sched_arr_time <int>,
#> # 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>
  • 对数据进行标准化以计算分组指标:
popular_dests %>%
 filter(arr_delay > 0) %>%
 mutate(prop_delay = arr_delay / sum(arr_delay)) %>%
 select(year:day, dest, arr_delay, prop_delay)
#> Source: local data frame [131,106 x 6]
#> Groups: dest [77]
#>
#> year month day dest arr_delay prop_delay
#> <int> <int> <int> <chr> <dbl> <dbl>
#> 1 2013 1 1 IAH 11 1.11e-04
#> 2 2013 1 1 IAH 20 2.01e-04
#> 3 2013 1 1 MIA 33 2.35e-04
#> 4 2013 1 1 ORD 12 4.24e-05
#> 5 2013 1 1 FLL 19 9.38e-05
#> 6 2013 1 1 ORD 8 2.83e-05
#> # ... with 1.311e+05 more rows

【注】:分组筛选器的作用相当于分组新变量加上未分组筛选器。一般不使用分组筛选器,除非是为了完成快速、粗略的数据处理,否则很难检查数据处理的结果是否正确。

在分组新变量和筛选器中最常使用的函数称为窗口函数(与用于统计的摘要函数相对)。你可以在相应的使用指南中学习到更多关于窗口函数的知识:vignette("windowfunctions")

习题解答

问题一

查看常用的新变量函数和筛选函数的列表。当它们与分组操作结合使用时,功能有哪些变化?

解答

  • 受影响的有: mean(), lead(), lag(), min_rank(), row_number(), mean(), sum(), sd()
tibble(x = 1:9,
       group = rep(c("a", "b", "c"), each = 3)) %>%
  mutate(x_mean = mean(x)) %>%
  group_by(group) %>%
  mutate(x_mean_2 = mean(x))
#> # A tibble: 9 x 4
#> # Groups:   group [3]
#>       x group x_mean x_mean_2
#>   <int> <chr>  <dbl>    <dbl>
#> 1     1 a          5        2
#> 2     2 a          5        2
#> 3     3 a          5        2
#> 4     4 b          5        5
#> 5     5 b          5        5
#> 6     6 b          5        5
#> # … with 3 more rows
  • 不受影响的有: 运算符(+,-,<,==,%%,%/%)
tibble(x = 1:9,
       group = rep(c("a", "b", "c"), each = 3)) %>%
  mutate(y = x + 2) %>%
  group_by(group) %>%
  mutate(z = x + 2)
#> # A tibble: 9 x 4
#> # Groups:   group [3]
#>       x group     y     z
#>   <int> <chr> <dbl> <dbl>
#> 1     1 a         3     3
#> 2     2 a         4     4
#> 3     3 a         5     5
#> 4     4 b         6     6
#> 5     5 b         7     7
#> 6     6 b         8     8
#> # … with 3 more rows

问题二

哪一架飞机(用机尾编号来识别,tailnum)具有最差的准点记录?

解答

我筛选至少飞行了20次的飞机。选择20是因为它是接近飞机飞行次数的上四分位数。

quantile(count(flights, tailnum)$n)
#>   0%  25%  50%  75% 100% 
#>    1   23   54  110 2512

将平均延误时间作为衡量标准。

flights %>%
  filter(!is.na(arr_delay)) %>%
  group_by(tailnum) %>%
  summarise(arr_delay = mean(arr_delay), n = n()) %>%
  filter(n >= 20) %>%
  filter(min_rank(desc(arr_delay)) == 1)
#> `summarise()` ungrouping output (override with `.groups` argument)
#> # A tibble: 1 x 3
#>   tailnum arr_delay     n
#>   <chr>       <dbl> <int>
#> 1 N203FR       59.1    41

问题三

如果想要尽量避免航班延误,那么应该在一天中的哪个时间搭乘飞机?

解答

可以按飞行时间分组,航班预定的时间越早,预计延误的时间就越低,因为延误会影响之后的航班。比如,早上的航班不容易受延误影响,是因为它们之前的航班较少。

flights %>%
  group_by(hour) %>%
  summarise(arr_delay = mean(arr_delay, na.rm = TRUE)) %>%
  arrange(arr_delay)
#> `summarise()` ungrouping output (override with `.groups` argument)
#> # A tibble: 20 x 2
#>    hour arr_delay
#>   <dbl>     <dbl>
#> 1     7    -5.30 
#> 2     5    -4.80 
#> 3     6    -3.38 
#> 4     9    -1.45 
#> 5     8    -1.11 
#> 6    10     0.954
#> # … with 14 more rows

问题四

计算每个目的地的延误总时间的分钟数,以及每架航班到每个目的地的延误时间比例。

解答

#每个目的地的延误总时间的分钟数
flights %>%
  filter(arr_delay > 0) %>%
  group_by(dest) %>%
  mutate(
    arr_delay_total = sum(arr_delay),
    arr_delay_prop = arr_delay / arr_delay_total
  ) %>%
  select(dest, month, day, dep_time, carrier, flight,
         arr_delay, arr_delay_prop) %>%
  arrange(dest, desc(arr_delay_prop))
#每架航班到每个目的地的延误时间比例
flights %>%
  filter(arr_delay > 0) %>%
  group_by(dest, origin, carrier, flight) %>%
  summarise(arr_delay = sum(arr_delay)) %>%
  group_by(dest) %>%
  mutate(
    arr_delay_prop = arr_delay / sum(arr_delay)
  ) %>%
  arrange(dest, desc(arr_delay_prop)) %>%
  select(carrier, flight, origin, dest, arr_delay_prop)

问题五

延误通常是由临时原因造成的:即使最初引起延误的问题已经解决,但因为要让前面的航班先起飞,所以后面的航班也会延误。使用 lag() 函数探究一架航班延误与前一架航班延误之间的关系。

解答

#计算同一机场前一航班的起飞延误。
lagged_delays <- flights %>%
 arrange(origin, month, day, dep_time) %>%
 group_by(origin) %>%
 mutate(dep_delay_lag = lag(dep_delay)) %>%
 filter(!is.na(dep_delay), !is.na(dep_delay_lag))

下面绘制了前一航班所有值与平均延误之间的关系。对于延误小于两小时的航班,前一航班的延误与当前航班的延误关系接近一条直线。在这之后,这种关系变得更加多变,因为长时间延误的航班与准时起飞的航班穿插在一起。大约8个小时后,一个航班延误之后可能会有一个航班准时起飞。

lagged_delays %>%
  group_by(dep_delay_lag) %>%
  summarise(dep_delay_mean = mean(dep_delay)) %>%
  ggplot(aes(y = dep_delay_mean, x = dep_delay_lag)) +
  geom_point() +
  scale_x_continuous(breaks = seq(0, 1500, by = 120)) +
  labs(y = "Departure Delay", x = "Previous Departure Delay")

问题六

查看每个目的地。你能否发现有些航班的速度快得可疑?(也就是说,这些航班的数据可能是错误的。)计算出到目的地的最短航线的飞行时间。哪架航班在空中的延误时间最长?

解答

先对数据进行标准化处理

standardized_flights <- flights %>%
  filter(!is.na(air_time)) %>%
  group_by(dest, origin) %>%
  mutate(
    air_time_mean = mean(air_time),
    air_time_sd = sd(air_time),
    n = n()
  ) %>%
  ungroup() %>%
  #加1是为了避免分母为0
  mutate(air_time_standard = (air_time - air_time_mean) / (air_time_sd + 1))

查看标准化后的航班分布

standardized_flights %>%
  arrange(air_time_standard) %>%
  select(
    carrier, flight, origin, dest, month, day,
    air_time, air_time_mean, air_time_standard
  ) %>%
  head(10) %>%
  print(width = Inf)

计算出到目的地的最短航线的飞行时间

flights %>%
 mutate(mph = distance / (air_time / 60)) %>%
 arrange(desc(mph)) %>%
 select(
   origin, dest, mph, year, month, day, dep_time, flight, carrier,
   dep_delay, arr_delay
 )

寻找在空中的延误时间最长的航班

air_time_delayed <-
 flights %>%
 group_by(origin, dest) %>%
 mutate(
   air_time_min = min(air_time, na.rm = TRUE),
   air_time_delay = air_time - air_time_min,
   air_time_delay_pct = air_time_delay / air_time_min * 100
 )
  arrange(desc(air_time_delay)) %>%
 select(
   air_time_delay, carrier, flight,
   origin, dest, year, month, day, dep_time,
   air_time, air_time_min
 ) %>%
 head() %>%
 print(width = Inf)

问题七

找出至少有两个航空公司的所有目的地。使用数据集中的信息对航空公司进行排名。

解答

计算这个排名有两个步骤。首先,找出有两家或两家以上航空公司服务的所有机场。然后,根据运营商服务的目的地数量对它们进行排名。

flights %>%
   # 找出有两家或两家以上航空公司服务的所有机场
   group_by(dest) %>%
   mutate(n_carriers = n_distinct(carrier)) %>%
   filter(n_carriers > 1) %>%
   # 根据运营商服务的目的地数量对它们进行排名
   group_by(carrier) %>%
   summarize(n_dest = n_distinct(dest)) %>%
   arrange(desc(n_dest))

本文分享自微信公众号 - 庄闪闪的R语言手册(Zss_R4ds),作者:我才是赵西西

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-12-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • R数据科学|3.4内容介绍及习题解答

    通过基于变量名的操作,select()函数可以让你生成一个有用的变量子集。基本用法如下:

    庄闪闪
  • R数据科学|3.5内容介绍及习题解答

    上节我们对选择现有的列进行了介绍与习题解答,现在对数据框添加新列进行介绍,这里使用mutate()函数,注意:mutate()总是将新列添加在数据集的最后。

    庄闪闪
  • R数据科学|5.4内容介绍及习题解答

    我们不建议使用这种方式,因为一个无效测量不代表所有测量都是无效的。此外,如果数据质量不高,若对每个变量都采取这种做法,那么你最后可能会发现数据已经所剩无几!

    庄闪闪
  • R数据科学|5.5.2内容介绍及课后习题解答

    要想对两个分类变量间的相关变动进行可视化表示,需要计算出每个变量组合中的观测数量。常用的两种方法有:

    庄闪闪
  • R数据科学|5.5.3内容介绍

    最简单的一种方法是:使用geom_point()画出散点图。你可以将相关变动看作点的模式。例如,你可以看到钻石的克拉数和价值之间存在一种指数关系:

    庄闪闪
  • R数据科学|3.6内容介绍

    上节我们对选择现有的列和使用mutate添加新列做了介绍。现在对数据框使用summarize()进行分组摘要进行介绍。函数功能:summarize()可以将数据...

    庄闪闪
  • R数据科学|5.5.1 内容介绍

    如果变动描述的是一个变量内部的行为,那么相关变动描述的就是多个变量之间的行为。相关变动是两个或多个变量以相关的方式共同变化所表现出的趋势。查看相关变动的最好 方...

    庄闪闪
  • R数据科学|5.3内容介绍

    上一期我们对《R数据科学》第3.7节进行了内容介绍和习题解答,细心的读者可以发现,这里直接跳转到了5.3节了。原因在于中间各节内容干货较少,也没有习题,所以就跳...

    庄闪闪
  • R数据科学|第十一章内容介绍

    因子在 R 中用于处理分类变量。从历史上看,因子远比字符串更容易处理。因此,R 基础包中的很多函数都自动将字符串转换为因子。

    庄闪闪
  • R数据科学|第九章内容介绍

    在实际应用中,我们常会涉及到多个数据表,必须综合使用它们才能找到关键信息。存在于多个表中的这种数据统称为关系数据。本章中的很多概念都和SQL中的相似,只是在dp...

    庄闪闪
  • R数据科学|第七章内容介绍

    tibble是一种简单数据框,它对data.frame的功能进行了一些修改,更易于使用。本文将介绍tidyverse的核心R包之一——tibble包

    庄闪闪
  • R数据科学|第十章内容介绍

    可以使用str_sub()函数来提取字符串的一部分。除了字符串参数外,str_sub() 函数中还 有 start 和 end 参数,它们给出了子串的位置(包括...

    庄闪闪
  • R数据科学|第八章内容介绍

    本文将介绍如何使用readr包将平面文件加载到 R 中,readr 也是 tidyverse 的核心 R包之一。

    庄闪闪
  • R数据科学|3.6习题解答

    这个问题是数据分析的一个基本问题:成本函数。作为分析人员,我们之所以对航班延误感兴趣,是因为对乘客来说代价高昂。在许多情况下,到达延迟更重要。在大多数情况下,迟...

    庄闪闪
  • R数据科学|5.5.1 习题解答

    前面对比了已取消航班和未取消航班的出发时间,使用学习到的知识对这个对比的可视化结果进行改善。

    庄闪闪
  • R数据科学|5.3课后习题解答

    研究 x、y 和 z 变量在 diamonds 数据集中的分布。你能发现什么?思考一下,对于一条钻石数据,如何确定表示长、宽和高的变量?

    庄闪闪
  • Python热文Top10,精选自1000篇文章

    【AI 科技大本营导读】每月一次的热文推荐又又又来啦~这次我们从近 1000 篇 Python 文章进行了筛选,挑选出了 10 篇(前 1%)值得一看的文章以飨...

    AI科技大本营
  • (数据科学学习手札41)folium基础内容介绍

      folium是js上著名的地理信息可视化库leaflet.js为Python提供的接口,通过它,我们可以通过在Python端编写代码操纵数据,来调用leaf...

    Feffery
  • (数据科学学习手札42)folium进阶内容介绍

      在上一篇(数据科学学习手札41)中我们了解了folium的基础内容,实际上folium在地理信息可视化上的真正过人之处在于其绘制图像的高度可定制化上,本文就...

    Feffery

扫码关注云+社区

领取腾讯云代金券