Menu

dplyr w R: filter, select, mutate, summarize w praktyce

Czym jest dplyr, jak go zainstalować i jak sześć podstawowych czasowników razem z potokiem zamienia chaotyczny kod na ramkach danych w czytelne potoki.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Czym jest dplyr

dplyr to najpopularniejszy pakiet R do przekształcania danych, "gramatyka danych" zbudowana z kilku czasowników. Każdy czasownik to funkcja, która przyjmuje ramkę danych, wykonuje dokładnie jedno zadanie (zostawia część wierszy, dodaje kolumnę, liczy podsumowanie grupy) i zwraca nową ramkę danych. Ponieważ każdy czasownik ma ten sam kształt (ramka danych wchodzi, ramka danych wychodzi), łączą się potokiem w ciągi kroków czytane z góry na dół jak przepis. dplyr to rdzeń tidyverse, rodziny pakietów (tidyr, ggplot2, readr), które mają wspólny projekt.

Wszystko, co robi dplyr, potrafi też bazowy R. Oto mała analiza w czystym bazowym R: przefiltruj wbudowany zbiór mtcars do samochodów 4-cylindrowych, oblicz nową kolumnę i uśrednij ją według liczby biegów. Ten przykład da się uruchomić:

To działa i to jest dobry R. Zauważ jednak, jak historia rozmywa się między indeksowaniem w nawiasach, przypisaniem przez $ i formułą. Wersja tej samej analizy w dplyr:

library(dplyr)

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

Cztery czasowniki w kolejności, w jakiej opowiada się je na głos. Ta czytelność to cały argument sprzedażowy, a przy potoku z dwudziestu kroków jest rozstrzygająca.

Fragmenty z dplyr na tej stronie są statyczne, bo ten edytor uruchamia tylko bazowy R. Żeby je uruchomić, zainstaluj dplyr na swoim komputerze, jak pokazano niżej.

Instalacja i wczytanie

Instalacja raz, a potem wczytanie w każdym skrypcie, który korzysta z pakietu:

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

Jeśli zamiast tego zainstalujesz install.packages("tidyverse"), dostaniesz dplyr i pakiety siostrzane. Przy wczytywaniu dplyr ostrzega, że przesłania stats::filter i stats::lag. To normalne, a nie błąd.

Sześć podstawowych czasowników

Każdy czasownik przyjmuje ramkę danych jako pierwszy argument, a nazwy kolumn gołe, bez cudzysłowów i przedrostków df$.

filter() zostawia wiersze, które spełniają warunek:

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

select() zostawia kolumny według nazwy, zakresu lub funkcji pomocniczej:

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

mutate() dodaje lub przekształca kolumny:

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

arrange() sortuje wiersze; owiń kolumnę w desc(), żeby sortować malejąco:

mtcars |> arrange(desc(mpg))

summarize() zwija wiersze do jednego wiersza podsumowania, a group_by() sprawia, że zwija je osobno dla każdej grupy:

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

group_by() sam w sobie nie robi nic widocznego: tylko oznacza ramkę danych, żeby następne summarize() (lub mutate()) działało grupa po grupie. Każdy czasownik ma pełny artykuł w tym rozdziale: filtrowanie wierszy, dodawanie kolumn, sortowanie i podsumowania w grupach.

Łączenie czasowników potokiem

Potok |> bierze wartość przed nim i przekazuje ją jako pierwszy argument funkcji po nim: x |> f(y) oznacza f(x, y). Ponieważ każdy czasownik dplyr przyjmuje i zwraca ramkę danych, czasowniki łączą się w nieskończoność:

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))

Przeczytaj to na głos: weź mtcars, zostaw samochody powyżej 100 koni mechanicznych, dodaj kolumnę z kilometrami na litr, pogrupuj według cylindrów, policz i uśrednij każdą grupę, posortuj według średniej. Żadnych zmiennych pośrednich, żadnego zagnieżdżania. Starszy kod używa %>% z pakietu magrittr zamiast |>; w pracy z dplyr są wymienne, a |> (wbudowany w R 4.1+) opisuje artykuł o potokach.

count() i n(): pomocnicy do liczenia

Liczenie jest tak częste, że dplyr ma skróty. n() daje liczbę wierszy w bieżącej grupie (działa tylko wewnątrz summarize() lub mutate()), a count() zwija cały taniec group_by() + summarize(n = n()) do jednego wywołania:

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

Jeśli łapiesz się na pisaniu group_by(x) |> summarize(n = n()), zastąp to przez count(x).

Słowo o tibble

Czasowniki dplyr często zwracają tibble, czyli wariant ramki danych z tidyverse. Tibble jest ramką danych (wszystko, co przyjmuje ramkę danych, przyjmuje też tibble), ale wypisuje się przyjaźniej: tylko pierwsze 10 wierszy, tylko kolumny, które się mieszczą, z typami pod każdą nazwą. Dwie różnice warto znać: tibble nigdy nie używa nazw wierszy (dlatego mtcars |> as_tibble() traci nazwy samochodów, bo tidyverse oczekuje, że identyfikatory będą w prawdziwej kolumnie), a indeksowanie pojedynczymi nawiasami zawsze zwraca tibble, zamiast czasem spadać do wektora. Żadna z tych różnic nie powinna cię na co dzień zaskakiwać; po prostu nie panikuj, gdy str() pokaże tbl_df.

Co warto zapamiętać

  • dplyr to gramatyka: sześć czasowników, z których każdy wykonuje jedno zadanie na ramce danych, połączonych potokiem.
  • filter() wybiera wiersze, select() wybiera kolumny, mutate() dodaje kolumny, arrange() sortuje, group_by() + summarize() agreguje.
  • x |> f(y) to f(x, y); potoki czyta się z góry na dół w kolejności, w jakiej coś się dzieje.
  • count() i n() pokrywają większość potrzeb związanych z liczeniem.
  • Bazowy R potrafi to wszystko; dplyr wygrywa czytelnością, gdy potoki rosną.

Dalej: filtrowanie i wybieranie podzbiorów w szczegółach, czyli idiomy z nawiasami w bazowym R i miejsce filter() z dplyr.

Najczęściej zadawane pytania

Czym jest dplyr w R?

dplyr to najpopularniejszy pakiet R do przekształcania ramek danych. Daje mały zestaw czasowników (filter(), select(), mutate(), arrange(), summarize(), group_by()), z których każdy robi jedną rzecz z ramką danych, a razem łączą się potokiem w czytelne ciągi kroków. Jest częścią tidyverse.

Jak zainstalować dplyr?

Uruchom raz install.packages("dplyr"), a potem library(dplyr) na początku każdego skryptu, który z niego korzysta. Instalacja tidyverse daje od razu dplyr i pakiety siostrzane (tidyr, ggplot2, readr).

Czy potrzebuję dplyr, czy wystarczy bazowy R?

Bazowy R potrafi wszystko, co dplyr (wybieranie podzbiorów, aggregate(), order()), i warto go znać, bo działa wszędzie bez żadnych zależności. dplyr zaczyna się opłacać, gdy potoki robią się długie: pięć połączonych czasowników czyta się jak zdanie, a odpowiednik w bazowym R jak łamigłówkę z zagnieżdżonych nawiasów.

Czym różni się summarize od summarise w dplyr?

Niczym. To ta sama funkcja w pisowni amerykańskiej i brytyjskiej; dplyr eksportuje obie. Używaj tej, której używa twój zespół, i trzymaj się jej konsekwentnie.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ