tidyverse初认识

1 第一题 编写代码

利用nycflights13包的flights数据集是2013年从纽约三大机场(JFK、LGA、EWR)起飞的所有航班的准点数据,共336776条记录。

  • 计算纽约三大机场2013起飞航班数和平均延误时间(可使用group_by, summarise函数)

    flights |> 
      group_by(origin) |> 
      summarise(n=n(),depm=mean(dep_delay,na.rm=T))
    # A tibble: 3 × 3
      origin      n  depm
      <chr>   <int> <dbl>
    1 EWR    120835  15.1
    2 JFK    111279  12.1
    3 LGA    104662  10.3
  • 计算不同航空公司2013从纽约起飞航班数和平均延误时间

    flights |> 
      group_by(carrier) |>
      summarise(n=n(),depm=mean(dep_delay,na.rm = T)) |> 
      arrange(desc(n))
    # A tibble: 16 × 3
       carrier     n  depm
       <chr>   <int> <dbl>
     1 UA      58665 12.1 
     2 B6      54635 13.0 
     3 EV      54173 20.0 
     4 DL      48110  9.26
     5 AA      32729  8.59
     6 MQ      26397 10.6 
     7 US      20536  3.78
     8 9E      18460 16.7 
     9 WN      12275 17.7 
    10 VX       5162 12.9 
    11 FL       3260 18.7 
    12 AS        714  5.80
    13 F9        685 20.2 
    14 YV        601 19.0 
    15 HA        342  4.90
    16 OO         32 12.6 
  • 计算纽约三大机场排名前三个目的地和平均飞行距离(可使用group_by, summarise, arrange, slice_max函数)

    flights |> 
      group_by(origin,dest) |>
      summarise(n=n(),distm=mean(distance)) |> 
      slice_max(n,n=3)
    `summarise()` has grouped output by 'origin'. You can override using the
    `.groups` argument.
    # A tibble: 9 × 4
    # Groups:   origin [3]
      origin dest      n distm
      <chr>  <chr> <int> <dbl>
    1 EWR    ORD    6100   719
    2 EWR    BOS    5327   200
    3 EWR    SFO    5127  2565
    4 JFK    LAX   11262  2475
    5 JFK    SFO    8204  2586
    6 JFK    BOS    5898   187
    7 LGA    ATL   10263   762
    8 LGA    ORD    8857   733
    9 LGA    CLT    6168   544

2 第二题 解释代码

  1. 代码含义:鸢尾花先按物种(Species)升序(setosa → versicolor → virginica);同物种内,按Sepal.Length降序(数值大的在前);若Sepal.Length相同,按Sepal.Width降序(数值大的在前)。

    iris是 R 语言自带的一个经典数据集,涵盖了不同种类鸢尾花的多种测量数据。tibble(iris) 将内置的iris数据集转换为tibble格式(一种增强的数据框,更易阅读和操作)。虽然iris本身已是数据框,但显式转换为tibble可确保后续操作兼容tidyverse语法。 %>%(管道操作符) 将左边的表达式的结果传递给右边的函数作为第一个参数,实现链式操作,使代码更清晰。 arrange(Species, across(starts_with(“Sepal”), desc) arrange() 用于对数据排序。 Species 作为第一个排序依据,默认按字母升序排列(如setosa → versicolor → virginica)。 across()函数用于对多个列应用操作。它的参数是一个列选择器和一个操作函数。 starts_with(“Sepal”)是一个列选择器,表示选择所有以”Sepal”开头的列(即Sepal.Length和Sepal.Width)。 desc()函数表示对这些列进行降序排序。 across(starts_with(“Sepal”), desc) 对以“Sepal”开头的列(即Sepal.Length和Sepal.Width)应用降序排列: 在每个Species组内,先按Sepal.Length从大到小排序。 若Sepal.Length相同,再按Sepal.Width从大到小排序。

    tibble(iris) %>% 
      arrange(Species,across(starts_with("Sepal"), desc))
    # A tibble: 150 × 5
       Sepal.Length Sepal.Width Petal.Length Petal.Width Species
              <dbl>       <dbl>        <dbl>       <dbl> <fct>  
     1          5.8         4            1.2         0.2 setosa 
     2          5.7         4.4          1.5         0.4 setosa 
     3          5.7         3.8          1.7         0.3 setosa 
     4          5.5         4.2          1.4         0.2 setosa 
     5          5.5         3.5          1.3         0.2 setosa 
     6          5.4         3.9          1.7         0.4 setosa 
     7          5.4         3.9          1.3         0.4 setosa 
     8          5.4         3.7          1.5         0.2 setosa 
     9          5.4         3.4          1.7         0.2 setosa 
    10          5.4         3.4          1.5         0.4 setosa 
    # ℹ 140 more rows
  2. 代码含义:每个性别组中,质量高于本组平均值的角色。 列数与原始 starwars 数据集一致,但行数减少。

    starwars %>% 调用 dplyr 内置的 starwars 数据集(包含《星球大战》角色的性别、质量、身高等信息)。 %>%(管道操作符)将数据传递到下一步操作,将左边的数据集传递给右边的函数作为第一个参数。 group_by(gender) 按 gender(性别)列对数据进行分组,后续操作会分别作用于每个性别组(如 “male”、“female”、NA 等组)。 filter(mass > mean(mass, na.rm = TRUE)) filter 是 dplyr 包中的函数,用于根据指定的条件筛选数据。 mass 是 starwars 数据集中表示角色体重的列。 mean(mass) 是组内均值(如男性组的平均质量、女性组的平均质量),而非全局均值。 在每个性别组内,仅保留 mass(质量/体重)大于该组平均值的行。 如果某行的 mass 为 NA,该行会被自动排除(filter 默认不保留无法判断条件的行)。 如果某性别组的所有 mass 均为 NA,则 mean(mass) 返回 NA,该组最终无数据保留。 na.rm = TRUE:计算均值时忽略缺失值(NA),避免因缺失值导致计算失败。

    starwars %>% 
      group_by(gender) %>% 
      filter(mass > mean(mass, na.rm = TRUE))
    # A tibble: 15 × 14
    # Groups:   gender [3]
       name    height   mass hair_color skin_color eye_color birth_year sex   gender
       <chr>    <int>  <dbl> <chr>      <chr>      <chr>          <dbl> <chr> <chr> 
     1 Darth …    202  136   none       white      yellow          41.9 male  mascu…
     2 Owen L…    178  120   brown, gr… light      blue            52   male  mascu…
     3 Beru W…    165   75   brown      light      blue            47   fema… femin…
     4 Chewba…    228  112   brown      unknown    blue           200   male  mascu…
     5 Jabba …    175 1358   <NA>       green-tan… orange         600   herm… mascu…
     6 Jek To…    180  110   brown      fair       blue            NA   <NA>  <NA>  
     7 IG-88      200  140   none       metal      red             15   none  mascu…
     8 Bossk      190  113   none       green      red             53   male  mascu…
     9 Ayla S…    178   55   none       blue       hazel           48   fema… femin…
    10 Gregar…    185   85   black      dark       brown           NA   <NA>  <NA>  
    11 Lumina…    170   56.2 black      yellow     blue            58   fema… femin…
    12 Zam We…    168   55   blonde     fair, gre… yellow          NA   fema… femin…
    13 Shaak …    178   57   none       red, blue… black           NA   fema… femin…
    14 Grievo…    216  159   none       brown, wh… green, y…       NA   male  mascu…
    15 Tarfful    234  136   brown      brown      blue            NA   male  mascu…
    # ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
    #   vehicles <list>, starships <list>
  3. 代码含义:name:保持原数据类型(通常为字符型)。homeworld:转换为因子型(母星名称作为分类标签)。species:转换为因子型(物种名称作为分类标签)。

    starwars %>% 调用 dplyr 内置的 starwars 数据集(包含《星球大战》角色的姓名、母星、物种、身高等信息)。 %>%(管道操作符)将数据传递到下一步操作,将左边的数据集传递给右边的函数作为第一个参数。 select(name, homeworld, species) select()用于选择数据集中的特定列:从数据集中仅保留 name(姓名)、homeworld(母星)、species(物种)三列,其余列(如 height、mass 等)被移除。 mutate(across(!name, as.factor)) mutate() 用于创建或修改列,此处修改数据类型。 across()函数用于对多个列应用操作。它的参数是一个列选择器和一个操作函数。 !name是一个列选择器,表示选择除name列之外的所有列。 as.factor是一个函数,用于将列转换为因子类型。 across(!name, as.factor) 表示对 除 name 列之外的所有列(即 homeworld 和 species)执行 as.factor() 函数: 将 homeworld 和 species 列从字符型(character)或任意类型转换为 因子型(factor)会被视为分类变量(如性别、物种类型),适合分类变量分析。

    starwars %>%
      select(name, homeworld, species) %>%
      mutate(across(!name, as.factor))
    # A tibble: 87 × 3
       name               homeworld species
       <chr>              <fct>     <fct>  
     1 Luke Skywalker     Tatooine  Human  
     2 C-3PO              Tatooine  Droid  
     3 R2-D2              Naboo     Droid  
     4 Darth Vader        Tatooine  Human  
     5 Leia Organa        Alderaan  Human  
     6 Owen Lars          Tatooine  Human  
     7 Beru Whitesun Lars Tatooine  Human  
     8 R5-D4              Tatooine  Droid  
     9 Biggs Darklighter  Tatooine  Human  
    10 Obi-Wan Kenobi     Stewjon   Human  
    # ℹ 77 more rows
  4. 代码含义:最终得到一个 tibble 数据,包含以下信息:所有原始列(如 mpg, cyl, hp 等),新增列 hp_cut(表示分箱区间),数据按 hp_cut 分组(覆盖了最初的 vs 分组)

    tibble(mtcars) %>% mtcars 是 R 语言自带的经典数据集,包含了 32 辆汽车的各种性能指标,如每加仑英里数(mpg)、马力(hp)、气缸数(cyl)等。 tibble 是 tibble 包(它是 tidyverse 的一部分)中的函数,用于把数据转换为 tibble 格式。tibble 是一种现代的数据框,在打印和处理方面比传统的数据框更友好。 %>%是管道操作符,将左边的表达式的结果传递给右边的函数作为第一个参数。 group_by(vs) %>% group_by 是 dplyr 包中的函数,用于按照指定的列对数据集进行分组。这里按照 vs 列(发动机形状,0 表示 V 型发动机,1 表示直列发动机)对 mtcars 数据集进行分组,后续操作会在每个分组内独立进行。 mutate(hp_cut = cut(hp, 3)) %>% mutate()是dplyr包中的一个函数,用于对数据集中的列进行变换或创建新列。 cut(hp, 3)函数将hp(马力)列的值分成3个区间,生成新列 hp_cut(如 (50,100]、(100,150]、(150,200]),每个区间会被赋予一个唯一的标签。 hp_cut是新创建的列,表示每个汽车的马力所属的区间。 group_by(hp_cut) 再次使用 group_by 函数,这次是按照新创建的 hp_cut 列对数据集进行分组,后续操作将基于这个新的分组进行。 最终数据按 hp_cut 区间分组,不再保留 vs 的分组。

    tibble(mtcars) %>%
      group_by(vs) %>%
      mutate(hp_cut = cut(hp, 3)) %>%
      group_by(hp_cut)
    # A tibble: 32 × 12
    # Groups:   hp_cut [6]
         mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb hp_cut     
       <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <fct>      
     1  21       6  160    110  3.9   2.62  16.5     0     1     4     4 (90.8,172] 
     2  21       6  160    110  3.9   2.88  17.0     0     1     4     4 (90.8,172] 
     3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1 (75.7,99.3]
     4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1 (99.3,123] 
     5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2 (172,254]  
     6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1 (99.3,123] 
     7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4 (172,254]  
     8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2 (51.9,75.7]
     9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2 (75.7,99.3]
    10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4 (99.3,123] 
    # ℹ 22 more rows

3 第三题 查找帮助理解函数

阅读 https://dplyr.tidyverse.org/reference/mutate-joins.html 内容,说明4个数据集链接函数函数的作用。分别举一个实际例子演示并解释其输出结果。

  1. inner_join() :仅保留两个数据集中键完全匹配的行(交集),丢弃所有不匹配的行。

    library(dplyr)
    
    df_party <- tibble(
      name = c("Luke", "Darth Vader", "Leia"),
      party = c("Rebel", "Empire", "Rebel")
    )
    
    df_planet <- tibble(
      name = c("Luke", "Leia", "Han"),
      planet = c("Tatooine", "Alderaan", "Corellia")
    )
    
    result_inner <- inner_join(df_party, df_planet, by = "name")
    print(result_inner)
    # A tibble: 2 × 3
      name  party planet  
      <chr> <chr> <chr>   
    1 Luke  Rebel Tatooine
    2 Leia  Rebel Alderaan
  2. left_join() :返回第一个数据框中的所有行及其在第二个数据框中匹配的行(左连接)。右侧无匹配的行用 NA 填充。

    result_left <- left_join(df_party, df_planet, by = "name")
    print(result_left)
    # A tibble: 3 × 3
      name        party  planet  
      <chr>       <chr>  <chr>   
    1 Luke        Rebel  Tatooine
    2 Darth Vader Empire <NA>    
    3 Leia        Rebel  Alderaan
  3. right_join() :返回第二个数据框中的所有行及其在第一个数据框中匹配的行(右连接)。左侧无匹配的行用 NA 填充。

    result_right <- right_join(df_party, df_planet, by = "name")
    print(result_right)
    # A tibble: 3 × 3
      name  party planet  
      <chr> <chr> <chr>   
    1 Luke  Rebel Tatooine
    2 Leia  Rebel Alderaan
    3 Han   <NA>  Corellia
  4. full_join() :返回两个数据框中的所有行(并集),如果没有匹配,则会有NA填充缺失值。

    result_full <- full_join(df_party, df_planet, by = "name")
    print(result_full)
    # A tibble: 4 × 3
      name        party  planet  
      <chr>       <chr>  <chr>   
    1 Luke        Rebel  Tatooine
    2 Darth Vader Empire <NA>    
    3 Leia        Rebel  Alderaan
    4 Han         <NA>   Corellia