data > opinion

Tom Alby

Prozentuale Anteile berechnen und kumulieren mit dplyr/Tidyverse

2022-01-09


Manchmal möchten wir eine schnelle Übersicht darüber gewinnen, wie viel Anteil die jeweiligen Ausprägungen eines Merkmals haben. summarise() aus dem dplyr-Package, das Teil des Tidyverse ist, kann schnell die Summe berechnen, was aber wenn wir nicht nur die Summe wissen wollen? Als Beispiel nehme ich den 1 Million Spotify Playlists-Datensatz, der schon wieder aus dem Netz verschwunden ist. Bei jeder Playlist ist die Anzahl der Follower angegeben. Wie sind die Follower verteilt? Zunächst laden wir das Tidyverse:

library(tidyverse)

Danach laden wir einen Teil der Daten, hier 400.000 PLaylists, damit haben die meisten Rechner schon genug zu tun:

spotify_full <- read_csv("~/Desktop/spotify-400k.csv", 
    col_names = FALSE)
## Rows: 26571361 Columns: 16
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (5): X1, X9, X10, X12, X16
## dbl (10): X3, X4, X5, X6, X7, X8, X11, X13, X14, X15
## lgl  (1): X2
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Zunächst einmal plotten wir ein Histogramm:

spotify_full %>%
  select(X3,X7) %>%
  unique() %>%
  ggplot(., aes(x = X7)) +
  geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Wie wir sehen, sehen wir nicht viel. Die meisten Playlists haben anscheinend nur 1 Follower. Die einfachste Übung ist nun durchzuzählen, wie viele Playlists 1 Follower haben, wie viele 2 Follower usw.:

spotify_full %>%
  select(X3,X7) %>%
  unique() %>%
  group_by(X7) %>%
  summarize(n = n()) 
## # A tibble: 378 × 2
##       X7      n
##    <dbl>  <int>
##  1     1 301745
##  2     2  59678
##  3     3  18813
##  4     4   7832
##  5     5   3917
##  6     6   2181
##  7     7   1303
##  8     8    859
##  9     9    625
## 10    10    393
## # … with 368 more rows

Aber wir sehen nun nicht, wie lange der Tail ist. Ist der gesamte Tail eventuell genau so groß wie die Anzahl der Playlists, die nur 1 Follower haben? Hier kommen nun die prozentualen Anteile ins Spiel:

spotify_full %>%
  select(X3,X7) %>%
  unique() %>%
  group_by(X7) %>%
  summarize(n = n()) %>%
  mutate(Anteil_in_Prozent = n/sum(n)*100)
## # A tibble: 378 × 3
##       X7      n Anteil_in_Prozent
##    <dbl>  <int>             <dbl>
##  1     1 301745           75.4   
##  2     2  59678           14.9   
##  3     3  18813            4.70  
##  4     4   7832            1.96  
##  5     5   3917            0.979 
##  6     6   2181            0.545 
##  7     7   1303            0.326 
##  8     8    859            0.215 
##  9     9    625            0.156 
## 10    10    393            0.0982
## # … with 368 more rows

Wie erwartet haben die meisten Playlists nur 1 Follower. Anscheinend haben um die 95% der Playlists 3 Follower oder weniger. Aber wie kriegen wir das nun genau raus ohne selber nachzurechnen? cumsum liefert uns die Möglichkeit, die Summen in einer Spalte zu addieren (kumulieren):

spotify_full %>%
  select(X3,X7) %>%
  unique() %>%
  group_by(X7) %>%
  summarize(n = n()) %>%
  mutate(Anteil_in_Prozent = n/sum(n)*100) %>%
  mutate(Anteile_kumuliert = cumsum(Anteil_in_Prozent))
## # A tibble: 378 × 4
##       X7      n Anteil_in_Prozent Anteile_kumuliert
##    <dbl>  <int>             <dbl>             <dbl>
##  1     1 301745           75.4                 75.4
##  2     2  59678           14.9                 90.4
##  3     3  18813            4.70                95.1
##  4     4   7832            1.96                97.0
##  5     5   3917            0.979               98.0
##  6     6   2181            0.545               98.5
##  7     7   1303            0.326               98.9
##  8     8    859            0.215               99.1
##  9     9    625            0.156               99.2
## 10    10    393            0.0982              99.3
## # … with 368 more rows
Tags: