Menu

Dodawanie i przekształcanie kolumn w R (mutate i bazowy R)

Jak dodawać, przekształcać i usuwać kolumny ramki danych: df$new <- ..., ifelse() dla kolumn warunkowych, transform() oraz mutate() z case_when() z dplyr.

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

Dodawanie kolumny: df$new <- value

Żeby dodać kolumnę w bazowym R, przypisz wartość do nazwy, która jeszcze nie istnieje. Wartość zwykle wylicza się z kolumn, które już są:

Wydarzyły się tu dwie rzeczy. orders$total dostało pełny wektor: price * qty jest liczone naraz dla każdego wiersza, bo arytmetyka w R jest wektorowa. orders$currency dostało pojedynczą wartość, którą R powielił (recykling) we wszystkich czterech wierszach. Każda inna długość to błąd (replacement has 3 rows, data has 4): w ten sposób R chroni cię przed źle wyrównaną kolumną.

Działa to, bo ramka danych to lista kolumn równej długości, a przypisanie nowego nazwanego elementu powiększa listę. Ten model wyjaśnia artykuł o ramkach danych.

Kolumny warunkowe: ifelse()

Kolumna, której wartość zależy od warunku, wymaga ifelse(), czyli wektorowego kuzyna if. Przyjmuje cały wektor warunków i zwraca wartość dla każdego wiersza:

Dlaczego nie zwykłe if? Bo if oblicza dokładnie jedno TRUE/FALSE, a gdy dostanie kolumnę, zgłasza błąd (the condition has length > 1). ifelse(test, yes, no) sprawdza każdy element i wybiera wartość dla każdego wiersza. Przy trzech lub więcej wynikach możesz zagnieżdżać:

Zagnieżdżenie na dwa poziomy jest w porządku; trzy lub więcej zamienia się w piramidę i właśnie do tego zbudowano case_when() z dplyr (poniżej). Samo if/else dla pojedynczej wartości opisuje artykuł o if-else.

Kilka kolumn naraz: transform()

transform() z bazowego R dodaje wiele kolumn w jednym wywołaniu, z samymi nazwami kolumn:

Zauważ, że transform() zwraca nową ramkę danych, więc wynik trzeba przypisać z powrotem, podczas gdy df$new <- ... modyfikuje w miejscu. Jedno ograniczenie: wyrażenia w jednym wywołaniu transform() nie widzą się nawzajem, więc discount = ifelse(total > 50, ...) tam zawiedzie (total jeszcze nie istnieje). Zrób to w dwóch krokach albo przez mutate(), które na to pozwala.

Modyfikowanie a tworzenie

Ta sama składnia przypisania nadpisuje istniejącą kolumnę; jedyna różnica polega na tym, czy kolumna już istniała:

Warto się tu zatrzymać: R nie ostrzega, gdy nadpisujesz kolumnę. Literówka w rodzaju df$prise <- round(df$price, 2) po cichu tworzy nową kolumnę zamiast poprawić starą. Po przekształceniu wywołaj na ramce print() albo str() i potwierdź, że zmieniło się to, co miało się zmienić.

Usuwanie kolumny

Przypisz NULL, żeby usunąć:

Kolumny nie ma, bez żadnych ceremonii. Żeby usunąć kilka, df[, c("a", "b")] (zostaw to, co wymieniasz) jest zwykle czytelniejsze niż wielokrotne NULL.

Sposób dplyr: mutate()

Czasownikiem dplyr do wszystkiego powyżej jest mutate(). Poniższe fragmenty są statyczne (piaskownica uruchamia tylko bazowy R), ale tak wyglądają te same operacje:

library(dplyr)

orders |>
    mutate(
        total    = price * qty,
        big      = total > 50        # can use total, defined one line up
    )

Dwie przewagi nad bazowym R. Po pierwsze, kolumny zdefiniowane w tym samym mutate() mogą odwoływać się do siebie nawzajem, po kolei, czego transform() odmawia. Po drugie, funkcje pomocnicze do warunków są lepsze niż zagnieżdżone ifelse():

students |>
    mutate(
        grade = if_else(score >= 60, "pass", "fail"),
        band  = case_when(
            score >= 85 ~ "high",
            score >= 60 ~ "mid",
            .default    = "low"
        )
    )

if_else() to surowsze ifelse() (obie gałęzie muszą mieć ten sam typ, co wyłapuje prawdziwe błędy). case_when() czyta się jak płaską listę par condition ~ value sprawdzanych od góry do dołu, z .default jako wartością awaryjną: to czytelny zamiennik piramidy ifelse(). Jak każdy czasownik dplyr, mutate() zwraca nową ramkę danych; to, jak łączy się z resztą, opisuje wprowadzenie do dplyr.

Co warto zapamiętać

  • df$new <- expression dodaje kolumnę; wyrażenie wykonuje się naraz dla każdego wiersza.
  • ifelse(test, yes, no) buduje kolumny warunkowe; zwykłe if tego nie potrafi.
  • transform() dodaje kilka kolumn w jednym wywołaniu, ale nie widzą się one nawzajem; mutate() to potrafi.
  • To samo przypisanie po cichu nadpisuje, więc po przekształceniu sprawdź pisownię.
  • df$col <- NULL usuwa kolumnę; case_when() zastępuje piramidy zagnieżdżonych ifelse().

Dalej: zmiana nazw kolumn, czyli names(), solidny idiom bazowego R, i rename() z dplyr.

Najczęściej zadawane pytania

Jak dodać nową kolumnę do ramki danych w R?

Przypisz wartość do nazwy kolumny, która jeszcze nie istnieje: df$total <- df$price * df$qty. R od razu tworzy kolumnę. Wartość może być pojedyncza (powielana w każdym wierszu) albo być wektorem wyliczonym z innych kolumn, pod warunkiem że jego długość zgadza się z liczbą wierszy.

Jak utworzyć kolumnę warunkową w R?

Użyj wektorowego ifelse(): df$grade <- ifelse(df$score >= 60, "pass", "fail") sprawdza naraz każdy wiersz. Nie używaj zwykłego if, bo obsługuje ono jeden warunek, a nie kolumnę. Przy więcej niż dwóch wynikach zagnieżdżaj wywołania ifelse() albo użyj case_when() z dplyr.

Co robi mutate() w R?

mutate() to czasownik dplyr do dodawania i przekształcania kolumn: df |> mutate(total = price * qty) zwraca kopię ramki danych z nową kolumną. W jednym wywołaniu może zdefiniować kilka kolumn, a późniejsze kolumny mogą korzystać z wcześniejszych, zdefiniowanych w tym samym mutate.

Jak usunąć kolumnę z ramki danych w R?

Przypisz jej NULL: df$notes <- NULL usuwa kolumnę w miejscu. W dplyr select(-notes) zwraca kopię bez niej.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ