《R for Data Science (2e)》免費中文翻譯 (第3章) --- Data transformation(1)

寫在前面

本系列推文為《R for Data Science (2)》的中文翻譯版本。所有內容都通過開源免費的方式上傳至Github,歡迎大家參與貢獻,詳細信息見:
Books-zh-cn 項目介紹:
Books-zh-cn:開源免費的中文書籍社區
r4ds-zh-cn Github 地址:
https://github.com/Books-zh-cn/r4ds-zh-cn
r4ds-zh-cn 網站地址:
https://books-zh-cn.github.io/r4ds-zh-cn/


目錄

  • 3.1 介紹

  • 3.2 行

  • 3.3 列

3.1 介紹

可視化是生成洞察力的重要工具,但很少有數據以完全符合你所需的形式提供,以制作你想要的圖形。通常情況下,你需要創建一些新的變量或摘要統計信息來回答你的問題,或者你可能只是想重命名變量或重新排序觀測結果,以便更輕松地處理數據。在本章中,你將學習如何使用 dplyr 包進行數據轉換(data transformation),并使用關于 2013 年從紐約市出發的航班的新數據集來介紹這些內容,并且你還將學習更多相關的知識!

本章的目標是為你提供轉換數據框的所有關鍵工具的概述。我們將從對數據框的行和列進行操作的函數開始,然后再回到管道操作符的討論,這是一個重要的工具,用于組合操作。然后,我們將介紹如何使用分組進行操作。最后,我們將通過一個案例研究展示這些函數的實際應用,并在后續章節中更詳細地討論這些函數,以便深入研究特定類型的數據 (e.g., numbers, strings, dates)。

3.1.1 先決條件

在本章中,我們將關注 dplyr 包,它是 tidyverse 的另一個核心成員。我們將使用 nycflights13 包中的數據說明關鍵思想,并使用 ggplot2 幫助我們理解數據。

library(nycflights13)
library(tidyverse)
#>?──?Attaching?core?tidyverse?packages?─────────────────────?tidyverse?2.0.0?──
#>???dplyr?????1.1.4???????readr?????2.1.5
#>???forcats???1.0.0???????stringr???1.5.1
#>???ggplot2???3.5.2???????tibble????3.3.0
#>???lubridate?1.9.4???????tidyr?????1.3.1
#>???purrr?????1.0.4?????
#>?──?Conflicts?───────────────────────────────────────?tidyverse_conflicts()?──
#>???dplyr::filter()?masks?stats::filter()
#>???dplyr::lag()????masks?stats::lag()
#>???Use?the?conflicted?package?(<http://conflicted.r-lib.org/>)?to?force?all?conflicts?to?become?errors

請仔細注意加載 tidyverse 時打印的沖突消息(conflicts message)。它告訴你 dplyr 覆蓋了 base R 中的一些函數。如果你想在加載 dplyr 后使用這些函數的 base 版本,你需要使用它們的全名:stats::filter()stats::lag()。到目前為止,我們大多忽略了一個函數來自哪個包,因為大多數時候它并不重要。但是,了解包可以幫助您找到幫助并找到相關函數,因此當我們需要準確了解某個函數來自哪個包時,我們將使用與 R 相同的語法:packagename::functionname()

3.1.2 nycflights13

為了探索基本的 dplyr 動詞(verbs),我們將使用 nycflights13::flights。該數據集包含 2013 年從紐約市起飛的所有 336,776 航班。數據來自美國 Bureau of Transportation Statistics,記錄在 ?flights 中。

flights
#>?#?A?tibble:?336,776?×?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
#>?#???336,770?more?rows
#>?#???11?more?variables:?arr_delay?<dbl>,?carrier?<chr>,?flight?<int>,?…

flights 是一個 tibble,一種特殊類型的 data frame,tidyverse 使用它來避免一些常見的問題。tibbles 和 data frame 之間最重要的區別是 tibbles 的打印方式;它們是為大型數據集設計的,因此它們只顯示前幾行,并且只顯示適合一個屏幕的列。有幾個選項可以查看所有內容。如果您使用的是 RStudio,最方便的可能是 View(flights),它將打開一個交互式的可滾動和可過濾的視圖。另外,您可以使用 print(flights, width = Inf) 來顯示所有列,或使用 glimpse()

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…

在這兩個視圖中,變量名稱后跟縮寫,告訴您每個變量的類型:<int> 是整數(integer)的縮寫,<dbl> 是雙精度(double)(又名實數)的縮寫,<chr> 用于字符(character)(也稱為字符串),<dttm> 用于日期時間(date-time)。這些很重要,因為您可以對列執行的操作在很大程度上取決于其”類型”。

3.1.3 dplyr 基礎

您將學習主要的 dplyr verbs(functions),這將使您能夠解決絕大多數數據操作挑戰。但在我們討論它們的個體差異之前,有必要先說明一下它們的共同點:

  1. 第一個參數始終是一個 data frame。

  2. 隨后的參數通常使用變量名稱(不帶引號)描述要對哪些列進行操作。

  3. 輸出總是一個新的 data frame。

因為每個 verb 都擅長做一件事,解決復雜問題通常需要組合多個 verbs,我們將使用豎線 |> 來實現。我們將在 Section 3.4 中更多地討論管道,但簡而言之,管道將其左側的東西傳遞給右側的函數,因此 x |> f(y) 等價于 f(x, y),而 x |> f(y) |> g(z) 等價于 g(f(x, y), z)。管道的最簡單發音是 “then”。即使您尚未了解詳細信息,也可以了解以下代碼:

flights?|>filter(dest?==?"IAH")?|>?group_by(year,?month,?day)?|>?summarize(arr_delay?=?mean(arr_delay,?na.rm?=?TRUE))

dplyr 的 verbs 根據操作對象分為四組:rows, columns, groups, or tables。在接下來的部分中,您將學習 rows、columns 和 groups 最重要的 verbs,然后我們將回到 Chapter 19 中用于 tables 的連接動詞。讓我們開始吧!

3.2 行

對數據集的行進行操作的最重要的 verbs 是 filter(),它改變了哪些行存在而不改變它們的順序,以及 arrange(),它改變了行的順序而不改變存在的行。這兩個函數只影響行,列保持不變。我們還將討論 distinct(),它可以找到具有唯一值的行,但與 arrange()filter() 不同的是,它還可以選擇性地修改列。

3.2.1 filter()

filter() 允許您根據列的值保留行。第一個參數是 data frame。第二個和后續參數是必須為真才能保留該行的條件。例如,我們可以找到所有晚點超過 120 分鐘(兩小時)的航班:

flights?|>?filter(dep_delay?>?120)
#>?#?A?tibble:?9,723?×?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??????848???????????1835???????853?????1001???????????1950
#>?2??2013?????1?????1??????957????????????733???????144?????1056????????????853
#>?3??2013?????1?????1?????1114????????????900???????134?????1447???????????1222
#>?4??2013?????1?????1?????1540???????????1338???????122?????2020???????????1825
#>?5??2013?????1?????1?????1815???????????1325???????290?????2120???????????1542
#>?6??2013?????1?????1?????1842???????????1422???????260?????1958???????????1535
#>?#???9,717?more?rows
#>?#???11?more?variables:?arr_delay?<dbl>,?carrier?<chr>,?flight?<int>,?…

除了 >(大于),您還可以使用 >=(大于或等于)、<(小于)、<=(小于或等于)、== (等于)和 !=(不等于)。您還可以將條件與 &, 結合起來以指示 “and”(檢查兩個條件)或與 | 結合以指示 “or”(檢查任一條件):

#?Flights?that?departed?on?January?1
flights?|>?filter(month?==?1?&?day?==?1)
#>?#?A?tibble:?842?×?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
#>?#???836?more?rows
#>?#???11?more?variables:?arr_delay?<dbl>,?carrier?<chr>,?flight?<int>,?…#?Flights?that?departed?in?January?or?February
flights?|>?filter(month?==?1?|?month?==?2)
#>?#?A?tibble:?51,955?×?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
#>?#???51,949?more?rows
#>?#???11?more?variables:?arr_delay?<dbl>,?carrier?<chr>,?flight?<int>,?…

組合 |== 時有一個有用的快捷方式:%in%。它保留變量等于右側值之一的行:

#?A?shorter?way?to?select?flights?that?departed?in?January?or?February
flights?|>?filter(month?%in%?c(1,?2))
#>?#?A?tibble:?51,955?×?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
#>?#???51,949?more?rows
#>?#???11?more?variables:?arr_delay?<dbl>,?carrier?<chr>,?flight?<int>,?…

我們將在 Chapter 12 中更詳細地回到這些比較和邏輯運算符。

當你運行 filter() 時,dplyr 執行過濾操作,創建一個新的數據框,然后打印它。它不會修改現有的 flights 數據集,因為 dplyr 函數從不修改其輸入。要保存結果,您需要使用賦值運算符,<-

jan1?<-?flights?|>?filter(month?==?1?&?day?==?1)

3.2.2 常見錯誤

當您開始使用 R 時,最容易犯的錯誤是在測試相等性時使用 = 而不是 ==filter() 會在發生這種情況時通知您:

flights?|>?filter(month?=?1)
#>?Error?in?`filter()`:
#>?!?We?detected?a?named?input.
#>???This?usually?means?that?you've?used?`=`?instead?of?`==`.
#>???Did?you?mean?`month?==?1`?

另一個錯誤是你像用英語那樣寫 “or” 語句:

flights?|>?filter(month?==?1?|?2)

這個能夠工作,因為它不會拋出錯誤,但它不會得到你想要的結果,因為 | 首先檢查條件 month == 1 然后檢查條件 2,這不是一個明智的檢查條件。我們將在 Section 12.3.2 中詳細了解這里發生的事情以及原因。

3.2.3 arrange()

arrange() 根據列(columns)的值更改行(rows)的順序。它接受一個 data frame 和一組要按順序排列的列名(column names)(或更復雜的表達式)。如果提供多個列名(column names),每個額外的列將用于解決前面列的值相等的情況。例如,下面的代碼按照出發時間排序,該時間跨越了四列。我們首先獲取最早的年份(years),然后在一年內獲取最早的月份(months),以此類推。

flights?|>?arrange(year,?month,?day,?dep_time)
#>?#?A?tibble:?336,776?×?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
#>?#???336,770?more?rows
#>?#???11?more?variables:?arr_delay?<dbl>,?carrier?<chr>,?flight?<int>,?…

arrange() 內部,您可以對列使用 desc() 函數,以便按降序(從大到小)重新排序數據框。例如,以下代碼按延誤時間從最長到最短的順序排序航班:

flights?|>?arrange(desc(dep_delay))
#>?#?A?tibble:?336,776?×?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?????9??????641????????????900??????1301?????1242???????????1530
#>?2??2013?????6????15?????1432???????????1935??????1137?????1607???????????2120
#>?3??2013?????1????10?????1121???????????1635??????1126?????1239???????????1810
#>?4??2013?????9????20?????1139???????????1845??????1014?????1457???????????2210
#>?5??2013?????7????22??????845???????????1600??????1005?????1044???????????1815
#>?6??2013?????4????10?????1100???????????1900???????960?????1342???????????2211
#>?#???336,770?more?rows
#>?#???11?more?variables:?arr_delay?<dbl>,?carrier?<chr>,?flight?<int>,?…

請注意,行的數量沒有改變 – 我們只是重新排列了數據,而沒有對其進行篩選。

3.2.4 distinct()

distinct() 函數用于在數據集中查找所有唯一的行,因此從技術上講,它主要操作行。然而,大多數情況下,您希望獲取某些變量的唯一組合,因此您也可以選擇性地提供列名:

#?Remove?duplicate?rows,?if?any
flights?|>?distinct()
#>?#?A?tibble:?336,776?×?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
#>?#???336,770?more?rows
#>?#???11?more?variables:?arr_delay?<dbl>,?carrier?<chr>,?flight?<int>,?…#?Find?all?unique?origin?and?destination?pairs
flights?|>?distinct(origin,?dest)
#>?#?A?tibble:?224?×?2
#>???origin?dest?
#>???<chr>??<chr>
#>?1?EWR????IAH??
#>?2?LGA????IAH??
#>?3?JFK????MIA??
#>?4?JFK????BQN??
#>?5?LGA????ATL??
#>?6?EWR????ORD??
#>?#???218?more?rows

另外,如果您在篩選唯一行時想要保留其他列,可以使用 .keep_all = TRUE 選項。

flights?|>?distinct(origin,?dest,?.keep_all?=?TRUE)
#>?#?A?tibble:?224?×?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
#>?#???218?more?rows
#>?#???11?more?variables:?arr_delay?<dbl>,?carrier?<chr>,?flight?<int>,?…

并非巧合,所有這些唯一的航班都是在 1 月 1 日:distinct() 函數將找到數據集中唯一行的第一個出現,并丟棄其余的重復行。

如果您想找到每個唯一行的出現次數,最好將 distinct() 替換為 count() 函數,并使用 sort = TRUE 參數按出現次數的降序排列它們。您可以在 Section 13.3 中了解更多關于 count() 函數的內容。

flights?|>count(origin,?dest,?sort?=?TRUE)
#>?#?A?tibble:?224?×?3
#>???origin?dest??????n
#>???<chr>??<chr>?<int>
#>?1?JFK????LAX???11262
#>?2?LGA????ATL???10263
#>?3?LGA????ORD????8857
#>?4?JFK????SFO????8204
#>?5?LGA????CLT????6168
#>?6?EWR????ORD????6100
#>?#???218?more?rows

3.2.5 練習

  1. 在每個條件的單個管道中,找到滿足條件的所有航班(flights):

  • 到達延遲了兩個或更長時間

  • Flew 到 Houston (IAH or HOU)

  • 由 United, American, 或 Delta 運營

  • 在夏天離開 (July, August, and September)

  • 遲到了超過兩個小時,但沒有晚出發

  • 被延遲至少一個小時,但在飛行中彌補了30分鐘以上

  1. flights 進行排序以查找起飛延誤(departure delays)時間最長的航班。查找早上最早起飛的航班。

  2. flights 進行排序以找到最快的航班。(提示:嘗試在你的函數中包含一個數學計算。)

  3. 2013 年每天都有航班嗎?

  4. 哪些航班飛行距離最遠?哪個航班飛行距離最短?

  5. 如果同時使用 filter()arrange(),那么使用它們的順序有什么關系嗎?為什么/為什么不?考慮結果以及功能必須完成的工作量。

3.3 列

有四個重要的 verbs 可以在不更改行的情況下影響列:mutate() 創建從現有列派生的新列,select() 更改存在的列,rename() 更改列的名稱,relocate() 更改列的位置。

3.3.1 mutate()

mutate() 的工作是添加根據現有列計算的新列。在轉換(transform)章節中,您將學習大量可用于操作不同類型變量的函數。現在,我們將堅持使用基本代數,它允許我們計算 gain、延遲航班在空中補足的時間以及以英里/小時為單位的 speed

flights?|>?mutate(gain?=?dep_delay?-?arr_delay,speed?=?distance?/?air_time?*?60)
#>?#?A?tibble:?336,776?×?21
#>????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
#>?#???336,770?more?rows
#>?#???13?more?variables:?arr_delay?<dbl>,?carrier?<chr>,?flight?<int>,?…

默認情況下,mutate() 會在數據集的右側添加新列,這使得很難看出這里發生了什么。我們可以使用 .before 參數將變量添加到左側:

flights?|>?mutate(gain?=?dep_delay?-?arr_delay,speed?=?distance?/?air_time?*?60,.before?=?1)
#>?#?A?tibble:?336,776?×?21
#>????gain?speed??year?month???day?dep_time?sched_dep_time?dep_delay?arr_time
#>???<dbl>?<dbl>?<int>?<int>?<int>????<int>??????????<int>?????<dbl>????<int>
#>?1????-9??370.??2013?????1?????1??????517????????????515?????????2??????830
#>?2???-16??374.??2013?????1?????1??????533????????????529?????????4??????850
#>?3???-31??408.??2013?????1?????1??????542????????????540?????????2??????923
#>?4????17??517.??2013?????1?????1??????544????????????545????????-1?????1004
#>?5????19??394.??2013?????1?????1??????554????????????600????????-6??????812
#>?6???-16??288.??2013?????1?????1??????554????????????558????????-4??????740
#>?#???336,770?more?rows
#>?#???12?more?variables:?sched_arr_time?<int>,?arr_delay?<dbl>,?…

. 表示 .before 是函數的參數,而不是我們正在創建的第三個新變量的名稱。您還可以使用 .after 來在變量之后添加,并且在 .before.after 中都可以使用變量名而不是位置。例如,我們可以在 day 之后添加新變量:

flights?|>?mutate(gain?=?dep_delay?-?arr_delay,speed?=?distance?/?air_time?*?60,.after?=?day)

或者,您可以使用 .keep 參數控制保留哪些變量。一個特別有用的參數是 "used",它指定我們只保留在 mutate() 步驟中涉及或創建的列。例如,以下輸出將僅包含變量 dep_delay, arr_delay, air_time, gain, hours, and gain_per_hour

flights?|>?mutate(gain?=?dep_delay?-?arr_delay,hours?=?air_time?/?60,gain_per_hour?=?gain?/?hours,.keep?=?"used")

請注意,由于我們尚未將上述計算的結果分配回 flights,因此新變量 gainhoursgain_per_hour 只會被打印出來,而不會存儲在數據框中。如果我們希望它們在數據框中可用以供將來使用,我們應該仔細考慮是否要將結果分配回 flights,用更多變量覆蓋原始數據框,或者分配給一個新對象。通常,正確的答案是一個新對象,該對象以信息性命名以指示其內容,例如 delay_gain,但您也可能有充分的理由覆蓋 flights

3.3.2 select()

獲取包含數百甚至數千個變量的數據集并不少見。在這種情況下,第一個挑戰通常只是關注您感興趣的變量。select() 允許您使用基于變量名稱的操作快速放大有用的子集:

  • 按名稱選擇列:

flights?|>?select(year,?month,?day)
  • 選擇 year 和 day(含)之間的所有列:

flights?|>?select(year:day)
  • 選擇除了 year 到 day(含)以外的所有列:

flights?|>?select(!year:day)

您也可以使用 - 代替 !(您很可能會在野外看到它);我們推薦 ! 因為它讀起來像 “not”,并且與 &| 結合得很好。

  • 選擇所有 characters 列:

flights?|>?select(where(is.character))

您可以在 select() 中使用許多輔助函數:

  • starts_with("abc"): 匹配以 “abc” 開頭的名稱。

  • ends_with("xyz"): 匹配以 “xyz” 結尾的名稱。

  • contains("ijk"): 匹配包含 “ijk” 的名稱。

  • num_range("x", 1:3): 匹配x1x2x3

有關詳細信息,請參閱 ?select。一但你了解正則表達式(the topic of Chapter 15),您還可以使用 matches() 來選擇與模式匹配的變量。

您可以在使用 =select() 時重命名變量。新名稱出現在 = 的左側,舊變量出現在右側:

flights?|>?select(tail_num?=?tailnum)
#>?#?A?tibble:?336,776?×?1
#>???tail_num
#>???<chr>???
#>?1?N14228??
#>?2?N24211??
#>?3?N619AA??
#>?4?N804JB??
#>?5?N668DN??
#>?6?N39463??
#>?#???336,770?more?rows

3.3.3 rename()

如果你想保留所有現有變量并且只想重命名一些變量,你可以使用 rename() 而不是 select()

flights?|>?rename(tail_num?=?tailnum)
#>?#?A?tibble:?336,776?×?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
#>?#???336,770?more?rows
#>?#???11?more?variables:?arr_delay?<dbl>,?carrier?<chr>,?flight?<int>,?…

如果你有一堆命名不一致的列,并且手動修復它們會很痛苦,請查看 janitor::clean_names(),它提供了一些有用的自動清理。

3.3.4 relocate()

使用 relocate() 移動變量。您可能希望將相關變量收集在一起或將重要變量移到前面。默認情況下,relocate() 將變量移動到前面:

flights?|>?relocate(time_hour,?air_time)
#>?#?A?tibble:?336,776?×?19
#>???time_hour???????????air_time??year?month???day?dep_time?sched_dep_time
#>???<dttm>?????????????????<dbl>?<int>?<int>?<int>????<int>??????????<int>
#>?1?2013-01-01?05:00:00??????227??2013?????1?????1??????517????????????515
#>?2?2013-01-01?05:00:00??????227??2013?????1?????1??????533????????????529
#>?3?2013-01-01?05:00:00??????160??2013?????1?????1??????542????????????540
#>?4?2013-01-01?05:00:00??????183??2013?????1?????1??????544????????????545
#>?5?2013-01-01?06:00:00??????116??2013?????1?????1??????554????????????600
#>?6?2013-01-01?05:00:00??????150??2013?????1?????1??????554????????????558
#>?#???336,770?more?rows
#>?#???12?more?variables:?dep_delay?<dbl>,?arr_time?<int>,?…

您還可以使用 .before.after 參數指定放置它們的位置,就像在 mutate() 中一樣:

flights?|>?relocate(year:dep_time,?.after?=?time_hour)
flights?|>?relocate(starts_with("arr"),?.before?=?dep_time)

3.3.5 練習

  1. 比較 dep_time, sched_dep_time, 和 dep_delay。您認為這三個數字之間有何關聯?

  2. 盡可能多地集思廣益,從 flights 中選擇 dep_timedep_delayarr_timearr_delay

  3. 如果您在 select() 調用中多次指定同一個變量的名稱,會發生什么情況?

  4. any_of() 函數有什么作用?為什么將它與該載體結合使用會有所幫助?

variables?<-?c("year",?"month",?"day",?"dep_delay",?"arr_delay")
  1. 運行以下代碼的結果是否讓您感到驚訝?默認情況下,select helpers 如何處理大寫和小寫?你怎么能改變這個默認值?

flights?|>?select(contains("TIME"))
  1. air_time 重命名為 air_time_min 以指示測量單位并將其移至數據框的開頭。

  2. 為什么以下不起作用,錯誤是什么意思?

flights?|>?select(tailnum)?|>?arrange(arr_delay)
#>?Error?in?`arrange()`:
#>???In?argument:?`..1?=?arr_delay`.
#>?Caused?by?error:
#>?!?object?'arr_delay'?not?found

?

--------------- 未完待續 ---------------

?

本期翻譯貢獻:

  • @TigerZ生信寶庫

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917418.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917418.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917418.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

rclone、rsync、scp使用總結

數據同步工具使用總結【rclone、rsync、scp】一、數據處理背景二、數據處理方法對比1、數據關系梳理2、不同工具處理方法3、經驗總結三、工具擴展知識1、rclone工具介紹&#xff08;1&#xff09;、rclone概述&#xff08;2&#xff09;、安裝工具及配置本地文件遷移到云上服務…

用latex+vscode+ctex寫畢業論文

文章目錄前言一、安裝latex二、安裝ctex包三、更新ctex包四、使用ctex文檔類前言 用latexvscodectex寫畢業論文。&#xff08;英文論文不用安裝ctex&#xff09; CTEX 宏集是面向中文排版的通用 LATEX 排版框架&#xff0c;為中文 LATEX 文檔提供了漢字輸出支持、標點壓縮、字…

深度學習·mmsegmentation基礎教程

mmsegmentation的使用教程 mmsegmentation微調方法總結 自定義自己的數據集&#xff1a;mmsegmentation\configs\_base_\datasets\ZihaoDataset_pipeline.py注冊&#xff1a;mmsegmentation\configs\_base_\datasets\__init__.py定義訓練和測試的pipeline&#xff1a;mmsegme…

InfluxDB 與 Node.js 框架:Express 集成方案(二)

四、優化與注意事項 &#xff08;一&#xff09;性能優化技巧 連接池管理&#xff1a;使用連接池可以有效減少創建和銷毀數據庫連接的開銷。在 Node.js 中&#xff0c;可以借助influx模塊結合第三方連接池庫&#xff0c;如generic-pool來實現連接池的管理 。通過設置連接池的…

單位長度上的RC參數

1inch1000mil25.4mm2.54cm 使用SI9000計算導線上電容電感參數并使用Q2D進行仿真驗證。使用SI9000建立一個阻抗為50歐的微帶線模型&#xff0c;后對該模型進行1GHz頻域計算 通過計算得到結果&#xff0c;可知1GHz頻率下單位傳輸線上的RLGC參數使用SI9000計算好單位長度上的RLGC參…

基于Dockerfile 部署一個 Flask 應用

Docker 與 Python&#xff1a;容器化部署應用&#xff0c;實現快速發布與彈性伸縮 以下是一個簡單的 Flask 應用 # app.py - 一個簡單的Flask應用 from flask import Flask import osapp Flask(__name__)app.route("/") def hello():env os.environ.get(FLASK_ENV,…

DFT設計中的不同階段介紹

在DFT&#xff08;Design for Test&#xff0c;可測試性設計&#xff09;軟件開發中&#xff0c;針對設計檢測的完整流程通常包含Setup&#xff08;設置&#xff09;、Analysis&#xff08;分析&#xff09;、Insertion&#xff08;插入&#xff09;和Verification&#xff08;…

自動化測試準備工作:概念篇

自動化 什么是自動化? 超市的自動閘門&#xff0c;不需要手動的開門關門生活中的自動動化案例有效的減少了人力的消耗&#xff0c;同時也提高了生活的質量。 軟件自動化測試同理&#xff0c;通過編寫自動化測試程序&#xff08;減少人力和時間的消耗&#xff0c;提高軟件的…

每日主題切換網頁:用純前端技術打造隨心情變化的動態界面

&#x1f3a8; 每日主題切換網頁&#xff1a;用純前端技術打造隨心情變化的動態界面 項目地址&#xff1a;https://github.com/hhse/daily-theme-switcher 在線演示&#xff1a;https://hhse.github.io/daily-theme-switcher 這里寫目錄標題&#x1f3a8; 每日主題切換網頁&…

TOPSIS(Technique for Order Preference by Similarity to Ideal Solution )簡介與簡單示例

前言 提醒&#xff1a; 文章內容為方便作者自己后日復習與查閱而進行的書寫與發布&#xff0c;其中引用內容都會使用鏈接表明出處&#xff08;如有侵權問題&#xff0c;請及時聯系&#xff09;。 其中內容多為一次書寫&#xff0c;缺少檢查與訂正&#xff0c;如有問題或其他拓展…

uniapp 富文本rich-text 文本首行縮進和圖片居中

1. uniapp 富文本rich-text 文本首行縮進和圖片居中 1.1. rich-text 文本首行縮進使用 rich-text 組件渲染html格式的代碼&#xff0c;常常因為不能自定義css導致文本不能縮進&#xff0c;以及圖片不能居中等問題&#xff0c;這里可以考慮使用js的replace方法&#xff0c;替換…

Apple基礎(Xcode③-Singbox Core)

brew install go open ~/.bash_profile export PATH="$PATH:$(go env GOPATH)/bin" 先確保工具鏈完整 go install github.com/sagernet/gomobile/cmd/gomobile@v0.1.4 go install github.com/sagernet/gomobile/cmd/gobind@v0.1.4 gomobile init -v # 關鍵:-v …

JVM學習日記(十四)Day14——性能監控與調優(一)

經過前幾篇的鋪墊&#xff0c;現在開始正式進入調優篇&#xff0c;也是大火實際用的到的和感興趣的&#xff0c;但是前期的知識積累還是有必要的&#xff0c;所以還對JVM基礎沒什么了解的&#xff0c;建議還是回看主包的前幾篇內容&#xff0c;當然看其他優秀的博主也是可以的。…

使用 Elasticsearch 和 AI 構建智能重復項檢測

作者&#xff1a;來自 Elastic Dayananda Srinivas 探索組織如何利用 Elasticsearch 檢測和處理貸款或保險申請中的重復項。 Elasticsearch 帶來了大量新功能&#xff0c;幫助你為你的使用場景構建最佳搜索方案。深入了解我們的示例 notebooks&#xff0c;開始免費云試用&#…

如何在不依賴 Office 的情況下轉換 PDF 為可編輯文檔

在日常工作里&#xff0c;我們經常需要處理各種文件格式的轉換問題&#xff0c;像Word轉PDF或者PDF轉Excel這樣的需求屢見不鮮。它是一款功能全面的PDF轉換工具&#xff0c;能夠幫助你輕松應對多種文檔處理任務。不僅能夠實現PDF與其他格式之間的轉換&#xff0c;如Word、Excel…

嵌入式學習筆記-MCU階段--DAY09

1. oled屏幕的接口IIC應用場合&#xff1a;2.IIC通信原理概念&#xff1a;IIC&#xff08;Inter-Integrated Circuit&#xff09;其實是IICBus簡稱&#xff0c;所以中文應該叫集成電路總線&#xff0c;它是一種串行通信總線&#xff0c;使用多主從架構&#xff0c;由飛利浦公司…

解決 Node.js 托管 React 靜態資源的跨域問題

在 Node.js 項目中托管 React 打包后的靜態資源時&#xff0c;可能會遇到跨域問題&#xff08;CORS&#xff09;。以下是幾種解決方案&#xff1a; 1. 使用 Express 中間件設置 CORS 頭 const express require(express); const path require(path); const app express();// …

【Linux】多路轉接之epoll

優化poll進行拷貝的開銷poll開銷過大將整個 pollfd 數組拷貝到內核態&#xff0c;以便內核檢查 fd 是否就緒&#xff08;從用戶態 → 內核態&#xff09;。內核檢查 fd 狀態&#xff0c;并填充 revents。將 pollfd 數組從內核態拷貝回用戶態&#xff0c;讓應用程序可以讀取 rev…

下載一個JeecgBoot-master項目 導入idea需要什么操作啟動項目

官網&#xff1a;開發環境搭建 | JEECG 文檔中心 一般做開發的電腦里都是有的&#xff0c;沒有的只能下載了 前端安裝 node官網:https://nodejs.org/zh-cnpnpm安裝:通過命令 后端安裝: jdk17 :https://www.oracle.com/cn/java/technologies/downloads/#java17maven :https://m…

解決 InputStream 只能讀取一次問題

是的&#xff0c;InputStream 的一個重要特性是它通常只能被讀取一次。這是因為&#xff1a;輸入流通常是單向的、順序訪問的數據源很多流&#xff08;如網絡流、文件流&#xff09;讀取后指針就移動了&#xff0c;無法回退有些流&#xff08;如Socket流&#xff09;甚至讀取后…