Unele dintre cele mai utile funcții Tidyverse

URMĂREȘTE-NE
16,065FaniÎmi place
1,142CititoriConectați-vă

(Acest articol a fost publicat pentru prima dată pe R – TomazTsqlși cu amabilitate a contribuit la R-bloggeri). (Puteți raporta problema legată de conținutul acestei pagini aici)


Doriți să vă distribuiți conținutul pe R-bloggeri? dați clic aici dacă aveți un blog, sau aici dacă nu aveți.

Funcții R pentru fiecare inginer de date care utilizează Tidyverse

Tidyverse a fost mult timp o colecție uimitoare de pachete R, în primul rând pentru ingineria datelor și știința datelor. Obișnuit printre aceste pachete este aceeași gramatică a limbii, design și structură grozave, ceea ce face știința datelor mai ușoară.

Motivația

Ingineria datelor este un pas important care ajută la îmbunătățirea gradului de utilizare a datelor, explorarea datelor și știința datelor. Prin urmare, pregătirea nevoilor de date trebuie făcută într-un mod ușor de citit, repetat și schimbat între alți ingineri.

Tidyverse are o mulțime de funcții de inginerie a datelor, înlănțuind diferite funcții pentru a obține majoritatea datelor. Toate cele șase exemple vor arăta combinații de funcții înlănțuite împreună pentru un set de rezultate grozav.

Următorul cod R se bazează pe seturi de date deschise numite mtcars, care este disponibil cu motorul R de bază.

1. Aplicarea de transformări sau modele datelor grupate

Combinarea datelor agregate cu datele grupate sau setul de date original este o tehnică frecvent utilizată de manipulare a datelor pentru extragerea și calcularea rapoartelor, procentelor, cumulative sau calculelor de creștere (de exemplu: YoY).

mtcars %>%
  group_by(cyl) %>%
  nest() %>%
  mutate(
    summary_stats_for_cyl = map(data, ~ summarise(.x, 
                                          mean_mpg_per_cyl_group = mean(mpg), 
                                          sd_mpg_per_cyl_group = sd(mpg)
                                          )
                        )
  ) %>% 
 unnest(cols = c(data, summary_stats_for_cyl)) 

Cu cuib() funcţia şi hartă() peste rezuma() putem obține pentru fiecare grup de mașini cu cilindru valori grupate pentru medie și abaterea standard.

Fig. 1: Statistici de grup per variabilă combinate cu setul de date original
Fig. 1: Statistici de grup per variabilă combinate cu setul de date original

2. Pivotați date ample și aplicați transformări tuturor variabilelor

Pivotarea datelor este o funcție puternică pentru calcularea agregărilor și, în acest exemplu, pivotăm mai mult și mai larg pe marca mașinii, unde toate valorile au aplicat funcția de agregare a medie().

În plus, adăugăm, de asemenea, media totală și abaterea standard totală a tuturor mărcilor de mașini pentru fiecare caracteristică a mașinii.

Codul Tidyverse este ușor de înțeles și ușor de citit.

mtcars %>%
   mutate(brand = word(rownames(.), 1)) %>%
   pivot_longer(cols = !brand, names_to = "characteristics", values_to = "value") %>%
   pivot_wider (names_from = "brand", values_from = "value", values_fn = ~ mean(.x, na.rm = TRUE)) %>%
   mutate(
    mean_charac = rowMeans(across(where(is.numeric)), na.rm = TRUE), 
    sd_charac = apply(across(where(is.numeric)), 1, sd, na.rm = TRUE) 
  )

Iar transformarea este informativă și utilă de ex: comparație între mărci.

Fig. 2: Pivotarea datelor pentru mărci de mașini și calculFig. 2: Pivotarea datelor pentru mărci de mașini și calcul
Fig. 2: Pivotarea datelor pentru mărci de mașini și calcul

3. Pivotarea datelor în scopul curățării datelor

Cazul obișnuit de inginerie a datelor este de a completa valorile lipsă sau de a le înlocui cu alte valori. În acest caz, transformăm datele largi în format lung, completăm valorile lipsă și revenim la formatul lat inițial. Motivul pentru pivotarea datelor este imputarea valorilor lipsă pe baza valorii mediane. Ar putea fi, de asemenea, ultima valoare nelipsă dintr-un set de date lung, sau poate fi, de asemenea, ordonată după timp, dimensiune sau ID de rulare și populată înapoi sau înainte.

df_ts <- tibble(
  id = 1:4,
  year_2021 = c(100, 200, NA, 400),
  year_2022 = c(150, NA, 300, 450),
  year_2024 = c(240, NA, NA, NA)
)

df_ts %>%
  pivot_longer(cols = starts_with("year"), names_to = "year", values_to = "value") %>%
  mutate(value = replace_na(value, median(value, na.rm = TRUE))) %>%
  pivot_wider(names_from = year, values_from = value)

În acest caz, se calculează valoarea mediană pentru toți anii (an_2021,an_2022, an_2024) (valoare = 240) și se înlocuiește cu toți indicatorii de valoare lipsă.

Fig. 3: Popularea valorilor lipsă cu funcții pivotFig. 3: Popularea valorilor lipsă cu funcții pivot
Fig. 3: Popularea valorilor lipsă cu funcții pivot

4. Interpolarea seriilor temporale și crearea de agregate rulante

Lucrul cu un set de date de serie temporală necesită adesea curățarea datelor prin înlocuirea valorilor aberante sau a valorilor lipsă. În plus, în mod normal dorim să creăm și caracteristici suplimentare din punctele de date originale.

În exemplul următor, vom adăuga datele lipsă la seria temporală (deoarece folosim date zilnice) utilizând complet() funcţie. În pasul următor, vom folosi interpolarea pe intervalele lipsă și vom suprascrie valorile din coloana de valori. Și, în sfârșit, vom folosi rollapply() funcția de calculare a mediei mobile pe intervalul de două zile (deci lățimea =2).

library(zoo)

df <- tibble(
  date = as.Date("2024-12-01") + c(0, 2, 4, 6, 8, 10, 11, 12, 13),
  value = c(10, NA, 30, NA, 50, 60, 50, NA, 40) 
 )

df %>%
  complete(date = seq.Date(min(date), max(date), by = "day")) %>%
  mutate(value = zoo::na.approx(value, na.rm = FALSE)) %>%
  mutate(rolling_avg = rollapply(value, width = 2, align = "right", fill = NA, FUN = mean))

Cu o combinație simplă de rollapply() şi na.aprox() funcții (ambele din bibliotecă grădină zoologică), putem face rapid o mulțime de pași într-o manieră ordonată.

Fig. 4: Intepolarea valorilor lipsă și calcularea statisticilor de rulareFig. 4: Intepolarea valorilor lipsă și calcularea statisticilor de rulare
Fig. 4: Intepolarea valorilor lipsă și calcularea statisticilor de rulare

5. Tabulări încrucișate cu marje și procente totale

Combinând puterea de bind_rows() funcţie, complet()funcții pivot și peste () putem crea o matrice de tabulare încrucișată între două variabile în mtcars; cil şi unelte.

cross_tab <- mtcars %>%
   count(cyl, gear) %>%
   complete(cyl = unique(mtcars$cyl), gear = unique(mtcars$gear), fill = list(n = 0)) %>% 
   pivot_wider(names_from = gear, values_from = n, values_fill = list(n = 0)) %>% 
   mutate(
     cyl = as.character(cyl),  
     Row_Total = rowSums(select(., -c(cyl)))  
   ) %>%
   mutate(
     Row_Percent = round(Row_Total / sum(Row_Total) * 100, 2) 
   ) %>%
   bind_rows(
     summarise(
       .,
       cyl = "Total",
       across(-c(cyl), sum, na.rm = TRUE),  
       Row_Percent = 100  
     )
   )
 
column_percent <- cross_tab %>%
 filter(cyl == "Total") %>% 
 mutate(
   cyl = "Column Percent",
   across(-c(cyl, Row_Total, Row_Percent), ~ round(.x / sum(.x) * 100, 2)),  
   Row_Total = NA, 
   Row_Percent = NA 
 )
 
final_table <- bind_rows(cross_tab, column_percent)
print(final_table)

Acest script calculează statisticile de marjă și procentele asupra valorilor pentru fiecare grup din coloana dată în raport cu fiecare rând.

Fig. 5: Calcularea tabelului încrucișat folosind Tidyverse

6. Aplicarea hărții funcțiilor din purrr

Pachetul purrr (ca parte a tidyverse) este un set puternic de funcții pentru programarea funcțională pentru lucrul cu funcții și vectori. Funcții hartă() este o modalitate ușoară și excelentă de a înlocui buclele for din codul dvs. Acest model de buclă peste un vector și de a face o operație la fiecare dintre elemente și de a stoca rezultatele este principalul avantaj al pachetului purrr față de funcțiile de bază R.

În fragmentul de mai jos, creăm o funcție numită apply_funs care acceptă un argument pentru cadrul de date (care este defalcat în vector individual) și aplică o familie de funcții statistice, cum ar fi mediana, media, abaterile standard și altele.

În ambele exemple, folosim funcția map și pentru bucla peste valorile unui vector sau bucla peste o listă de vectori (în acest caz un cadru de date).

# for vector
apply_funs_vec <- function(x, ...) {
  purrr::map_dbl(list(...), ~ .x(x))
}

apply_funs_vec(mtcars$cyl, mean, median, sd, min, max)

#for dataframe (or vector)
apply_funs <- function(x, ...) {
  funs <- list(...)
  fun_names <- as.character(substitute(list(...))(-1))
  
  if (is.data.frame(x)) {
    x <- dplyr::select_if(x, is.numeric)
    results <- purrr::map_dfc(x, function(column) {
      purrr::map_dbl(funs, ~ .x(column))
    })
    results <- as.data.frame(results)
    rownames(results) <- fun_names
    return(results)
    
  } else if (is.numeric(x)) {
    results <- purrr::set_names(purrr::map_dbl(funs, ~ .x(x)), fun_names)
    return(results)
  } else print("Need numeric input")
}

apply_funs(mtcars, mean, median, sd, min, max)
apply_funs(mtcars$cyl, mean, median, sd, min, max)


## or with map_df
mtcars_res <- mtcars %>% 
  map_df( ~ list(
                mean = mean(.), 
                median = median(.),
                sd = sd(.),
                min = min(.),
                max = max(.)
    )
)

mtcars_res <- t(mtcars_res)
colnames(mtcars_res) <- names(mtcars)
mtcars_res

Și rezultatul funcției map() este o statistică descriptivă generală pentru toate variabilele numerice.

Fig.: 2: Aplicarea funcţiilor statistice peste data.frameFig.: 2: Aplicarea funcţiilor statistice peste data.frame
Fig.: 6: Aplicarea funcţiilor statistice peste data.frame

Concluzie

Această listă scurtă de combinații Tidyverse nu este doar o listă utilă, ci și o afișare a unui set de instrumente puternic de funcționalități pentru munca de zi cu zi pentru oamenii de știință de date și roluri legate de date. Cu limbajul Tidyverse, codul dvs. va fi, de asemenea, mai simplu și mai ușor de citit, făcându-l astfel mai ușor de gestionat.

Ca întotdeauna, codul este disponibil în depozitul meu Github.

La mulți ani R-Coding și la mulți ani 2025!

Articolul a fost publicat pentru prima dată pe Medium (31.12.2024)

Dominic Botezariu
Dominic Botezariuhttps://www.noobz.ro/
Creator de site și redactor-șef.

Cele mai noi știri

Pe același subiect

LĂSAȚI UN MESAJ

Vă rugăm să introduceți comentariul dvs.!
Introduceți aici numele dvs.