Menu

dplyr ב-R: filter, select, mutate, summarize, מבוא מעשי

מה זה dplyr, איך מתקינים אותה, ואיך שישה פעלי ליבה יחד עם ה-pipe הופכים קוד מבולגן של data frames לצינורות קריאים.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

מה זה dplyr

dplyr היא החבילה הפופולרית ביותר ב-R לעיבוד נתונים: "דקדוק של נתונים" שבנוי מקומץ פעלים. כל פועל הוא פונקציה שמקבלת data frame, עושה בדיוק עבודה אחת (משאירה חלק מהשורות, מוסיפה עמודה, מחשבת סיכום לקבוצה) ומחזירה data frame חדש. מכיוון שלכל פועל יש אותה צורה, data frame נכנס ו-data frame יוצא, הם מתחברים עם ה-pipe לצינורות שנקראים מלמעלה למטה כמו מתכון. dplyr היא הליבה של ה-tidyverse, משפחה של חבילות (tidyr, ggplot2, readr) שחולקות את העיצוב הזה.

כל מה ש-dplyr עושה, גם base R עושה. הנה ניתוח קטן ב-base R טהור: סינון נתוני mtcars המובנים למכוניות עם 4 צילינדרים, חישוב עמודה חדשה, וחישוב הממוצע שלה לפי מספר ההילוכים. את זה אפשר להריץ:

זה עובד, וזה R טוב. אבל שימו לב איך הסיפור מרוח על פני אינדוקס בסוגריים, השמה עם $ ונוסחה. גרסת ה-dplyr של אותו ניתוח:

library(dplyr)

mtcars |>
    filter(cyl == 4) |>
    mutate(kml = mpg * 0.425) |>
    group_by(gear) |>
    summarize(avg_kml = round(mean(kml), 1))

ארבעה פעלים, בסדר שבו הייתם מסבירים אותם בקול. הקריאות הזו היא כל טיעון המכירה, ובצינור של עשרים שלבים היא מכרעת.

קטעי ה-dplyr בעמוד הזה סטטיים כי העורך הזה מריץ רק base R: כדי להריץ אותם, התקינו את dplyr על המחשב שלכם כפי שמוצג בהמשך.

התקנה וטעינה

התקנה חד-פעמית, ואז טעינה בכל סקריפט שמשתמש בה:

install.packages("dplyr")   # once, per machine
library(dplyr)              # every script

התקנה עם install.packages("tidyverse") במקום זאת מביאה את dplyr ואת האחיות שלה. כש-dplyr נטענת, היא מזהירה שהיא מסתירה את stats::filter ואת stats::lag: זה רגיל, לא שגיאה.

ששת פעלי הליבה

כל פועל מקבל את ה-data frame כארגומנט הראשון ואת שמות העמודות חשופים, בלי מירכאות ובלי קידומות df$.

filter() משאיר שורות שמתאימות לתנאי:

mtcars |> filter(mpg > 25)
mtcars |> filter(cyl == 4, hp < 70)   # comma = AND

select() משאיר עמודות לפי שם, טווח או פונקציית עזר:

mtcars |> select(mpg, cyl, hp)
mtcars |> select(mpg:hp)              # a range of adjacent columns
mtcars |> select(starts_with("d"))    # disp, drat

mutate() מוסיף עמודות או משנה אותן:

mtcars |> mutate(kml = mpg * 0.425, heavy = wt > 3.5)

arrange() ממיין שורות: עטפו עמודה ב-desc() למיון יורד:

mtcars |> arrange(desc(mpg))

summarize() מכווץ שורות לשורת סיכום אחת, ו-group_by() גורם לו לכווץ לפי קבוצה במקום:

mtcars |>
    group_by(cyl) |>
    summarize(n = n(), avg_mpg = mean(mpg))

group_by() לא עושה שום דבר גלוי בעצמו: הוא רק מתייג את ה-data frame כך שה-summarize() (או ה-mutate()) הבא יעבוד קבוצה אחר קבוצה. לכל פועל יש מסמך מלא בפרק הזה: סינון שורות, הוספת עמודות, מיון וסיכומים לפי קבוצות.

שרשור פעלים עם ה-pipe

ה-pipe |> לוקח את הערך שלפניו ומזין אותו כארגומנט הראשון של הפונקציה שאחריו: x |> f(y) פירושו f(x, y). מכיוון שכל פועל של dplyr מקבל ומחזיר data frame, הפעלים משתרשרים ללא הגבלה:

mtcars |>
    filter(hp > 100) |>
    mutate(kml = mpg * 0.425) |>
    group_by(cyl) |>
    summarize(cars = n(), avg_kml = round(mean(kml), 1)) |>
    arrange(desc(avg_kml))

קראו את זה בקול: קחו את mtcars, השאירו מכוניות מעל 100 כוחות סוס, הוסיפו עמודה של קילומטרים לליטר, קבצו לפי צילינדרים, ספרו וחשבו ממוצע לכל קבוצה, מיינו לפי הממוצע. בלי משתני ביניים, בלי קינון. קוד ישן יותר משתמש ב-%>% מהחבילה magrittr במקום ב-|>: לעבודה עם dplyr הם ניתנים להחלפה, ו-|> (מובנה ב-R 4.1 ומעלה) מוסבר במסמך על pipes.

count() ו-n(): פונקציות העזר לספירה

ספירה כל כך נפוצה ש-dplyr כוללת קיצורי דרך. n() נותנת את מספר השורות בקבוצה הנוכחית (תקפה רק בתוך summarize() או mutate()), ו-count() מכווצת את כל הריקוד של group_by() + summarize(n = n()) לקריאה אחת:

mtcars |> count(cyl)                    # rows per cyl value
mtcars |> count(cyl, gear, sort = TRUE) # two groupers, biggest first

אם אתם מוצאים את עצמכם כותבים group_by(x) |> summarize(n = n()), החליפו את זה ב-count(x).

הערה על tibbles

פעלי dplyr מחזירים לעיתים קרובות tibble, הגרסה של ה-tidyverse ל-data frame. tibble הוא data frame (כל מה שמקבל data frame מקבל tibble), עם הדפסה ידידותית יותר: רק 10 השורות הראשונות, רק העמודות שנכנסות, עם הסוגים מוצגים מתחת לכל שם. שני הבדלים שכדאי להכיר: ל-tibbles אין אף פעם שמות שורות (ולכן mtcars |> as_tibble() מאבד את שמות המכוניות: ה-tidyverse מצפה שמזהים יגורו בעמודה אמיתית), ואינדוקס בסוגריים בודדים תמיד מחזיר tibble במקום לרדת לפעמים לווקטור. אף אחד מהם לא אמור להפתיע אתכם ביום-יום; רק אל תיבהלו כש-str() אומרת tbl_df.

מה לקחת מכאן

  • dplyr היא דקדוק: שישה פעלים, כל אחד עושה עבודה אחת ל-data frame, משורשרים עם ה-pipe.
  • filter() בוחר שורות, select() בוחר עמודות, mutate() מוסיף עמודות, arrange() ממיין, group_by() + summarize() מסכמים.
  • x |> f(y) הוא f(x, y): צינורות נקראים מלמעלה למטה בסדר שבו הדברים קורים.
  • count() ו-n() מכסות את רוב צורכי הספירה.
  • Base R יכול לעשות את כל זה; dplyr מנצחת בקריאות ברגע שהצינורות גדלים.

הבא בתור: סינון וחיתוך לעומק: ביטויי הסוגריים של base R, ואיפה filter() של dplyr משתלב.

שאלות נפוצות

מה זה dplyr ב-R?

dplyr היא החבילה הנפוצה ביותר ב-R לעיבוד data frames. היא נותנת לכם קבוצה קטנה של פעלים, filter(), select(), mutate(), arrange(), summarize(), group_by(), שכל אחד מהם עושה דבר אחד ל-data frame, והם משתרשרים יחד עם ה-pipe לצינורות קריאים. היא חלק מה-tidyverse.

איך מתקינים את dplyr?

הריצו install.packages("dplyr") פעם אחת, ואז library(dplyr) בראש כל סקריפט שמשתמש בה. התקנה של tidyverse במקום זאת נותנת לכם את dplyr ואת החבילות האחיות שלה (tidyr, ggplot2, readr) בבת אחת.

האם אני צריך את dplyr, או ש-base R מספיק?

Base R יכול לעשות כל מה ש-dplyr עושה, חיתוך, aggregate(), order(), ושווה להכיר אותו כי הוא עובד בכל מקום בלי שום תלויות. dplyr מצדיקה את ההתקנה כשהצינורות מתארכים: חמישה פעלים משורשרים נקראים כמו משפט, ואילו המקבילה ב-base נקראת כמו חידות של סוגריים מקוננים.

מה ההבדל בין summarize ל-summarise ב-dplyr?

אין הבדל. זו אותה פונקציה בכתיב אמריקאי ובכתיב בריטי; dplyr מייצאת את שתיהן. השתמשו במה שהצוות שלכם משתמש בו והיו עקביים.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל