4  Digitale Verhaltensdaten

Um einen ersten Eindruck davon zu erhalten, welche Möglichkeiten die Auswertung digitaler Verhaltensdaten (“digital trace data”) für die Forschung eröffnen kann, schauen wir uns exemplarisch die über den YouTube-Data-Takeout erhältlichen Daten an, welche uns beispielsweise durch Studienteilnehmer:innen in Form von Datenspenden (“Data Donations”) zu Verfügung gestellt werden können.

4.1 Anfrage YouTube Takeout Daten

Sofern Sie einen YouTube-Account / ein Google-Konto besitzen, können die Daten folgendermaßen heruntergeladen werden:

  1. Rufen Sie die Adresse takeout.google.com auf und melden Sie sich, sofern nicht bereits geschehen, mit Ihrem Google-Account an, der Ihrem YouTube-Konto zugeordnet ist.
  2. Wählen Sie unter “Neuen Export erstellen”, sofern dort zurzeit alle Produkte markiert sind, die Option “Auswahl aufheben”, um bei allen Produkten den Haken zu entfernen.
  3. Scrollen Sie in der Liste der Produkte weit nach unten bis Sie “YouTube und YouTube Music” finden (die Liste ist alphabetisch sortiert).
  4. Setzen Sie nur bei diesem Produkt (“YouTube und YouTube Music”) einen Haken.
  5. Wählen Sie anschließend den darunter befindlichen linken Button auf dem (vermutlich) “Mehrere Formate” steht. Ändern Sie bei “Verlauf” die Option von “HTML” auf “JSON” und bestätigen Sie mit “OK”. Auf dem Button sollte nun “JSON-Format” stehen.
  6. Auf dem rechten Button steht (vermutlich) standardmäßig “Alle YouTube Daten eingeschlossen”. Dies können Sie so belassen (dann können Sie sich alle Daten ansehen, die Google auf YouTube über Sie gesammelt hat). Wenn Sie möchten, können Sie jedoch auch einzelne Datenpunkte abwählen, die Sie als zu sensibel betrachten.
  7. Wählen Sie am Seitenende den Button “Nächster Schritt”.
  8. Wählen Sie, wie Sie die Daten empfangen wollen. Ich empfehle hier “Download-Link per E-Mail senden”. Wählen Sie außerdem bei Häufigkeit “Einmal exportieren” und bei Dateityp “ZIP”. Die angegebene Dateigröße ist i.d.R. irrelevant, diese können Sie bei der Standardeinstellung belassen.
  9. Wählen Sie den Button “Export erstellen”.
  10. Normalerweise dauert der Datenexport, sofern Sie nur YouTube ausgewählt haben, nur wenige Sekunden. Warten Sie 20-30 Sekunden und laden Sie dann die Seite neu. Nun sollten Sie oben auf der Seite bei “Ihr letzer Export” einen Button zum “Herunterladen” der Daten finden. Wählen Sie diesen aus und laden Sie die Daten herunter. Speichern Sie sie auf Ihrem Computer an einem sicheren Ort ab.
  11. Sollte der Daten-Export unerwartet doch länger dauern, erhalten Sie eine E-Mail an Ihre Google-Mail Adresse (mail.google.com), sobald der Download bereitsteht. Laden Sie die Daten dann über den dort bereitgestellten Link herunter.

4.2 YouTube Wiedergabeverlauf

Zu Beginn laden wir zunächst das tidyverse Paket und setzen ein schöneres Theme für alle Grafiken, die wir erstellen.

library(tidyverse)
theme_set(theme_minimal())

Anschließend laden wir die aus dem Take-Out erhältlichen Dateien Wiedergabeverlauf.json und Abos.csv in unsere R-Umgebung. Die Daten aus der JSON-Datei wandeln wir direkt in das uns bekannte tibble-Format um und erstellen einige neue Variablen, die bspw. den Wochentag oder die Uhrzeit der YouTube-Nutzung abbilden.

yt_data <-
  jsonlite::fromJSON("Wiedergabeverlauf.json") |>
  as_tibble() |>
  select(title, titleUrl, time, subtitles) |>
  unnest(subtitles) |>
  rename(title_url = titleUrl, channel = name, channel_url = url) |>
  mutate(
    timestamp = lubridate::as_datetime(time),
    day = as.Date(timestamp),
    hour = lubridate::hour(timestamp),
    weekday = lubridate::wday(timestamp, label = TRUE, week_start = 1),
    .keep = "unused"
  )

abos <-
  read_csv("Abos.csv")

In einem nächsten Schritt können wir die Daten explorieren, um mehr darüber zu erfahren, welche Informationen sie enthalten. Wir wissen zum Beispiel, dass die Testperson gerne Musik der Band “Nothing But Thieves” hört. Wir können also auszählen, wie viele der Videos in den gespendeten Daten das Wort “Thieves” in unterschiedlichen Schreibweisen enthalten oder diese für weitere Analyse herausfiltern.

yt_data |>
  filter(str_detect(title, "thieves|Thieves|THIEVES"))
# A tibble: 25 × 8
  title       title_url channel channel_url timestamp           day         hour
  <chr>       <chr>     <chr>   <chr>       <dttm>              <date>     <int>
1 Nothing Bu… https://… BBCRad… https://ww… 2025-03-22 19:57:01 2025-03-22    19
2 Nothing Bu… https://… cultur… https://ww… 2025-03-21 09:59:07 2025-03-21     9
3 Nothing Bu… https://… Virgin… https://ww… 2025-03-21 09:57:38 2025-03-21     9
4 Nothing Bu… https://… BBCRad… https://ww… 2025-03-21 09:53:41 2025-03-21     9
5 Nothing Bu… https://… Nachi … https://ww… 2025-03-21 09:45:09 2025-03-21     9
# ℹ 20 more rows
# ℹ 1 more variable: weekday <ord>

Außerdem können wir uns das Nutzungsverhalten auf verschiedenen Ebenen ansehen und visualisieren.

yt_data %>%
  count(day) %>%
  ggplot(aes(x = day, y = n)) +
  geom_col() +
  labs(title = "YouTube videos viewed per day")

yt_data %>%
  count(hour) %>%
  ggplot(aes(x = hour, y = n)) +
  geom_col() +
  labs(title = "YouTube videos viewed per hour of day")

yt_data %>%
  count(weekday) %>%
  ggplot(aes(x = weekday, y = n)) +
  geom_col() +
  labs(title = "YouTube videos viewed per day of the week")

Abschließend können wir uns anschauen, wie viele der geschauten Videos von Kanälen stammen, die die Testperson abonniert hat.

yt_data |>
  mutate(channel_id = str_extract(channel_url, "(?<=channel/).*")) |>
  filter(channel_id %in% str_extract(abos$`Kanal-URL`, "(?<=channel/).*")) |>
  count()
# A tibble: 1 × 1
      n
  <int>
1    31

4.3 Video-Metadaten

Weitere Informationen über die Videos können wir über eine API von Google abrufen. Glücklicherweise gibt es diverse R-Pakete, die uns den Abruf von Informationen über diese API erleichtern. Um Zugang zur API zu erhalten, müssen wir uns jedoch autorisieren.

Hierzu melden wir uns in der — zugegebenermaßen sehr unübersichtlichen — Google Cloud Console an (https://console.cloud.google.com) und erstellen ein “Neues Projekt”:

Nachdem das Projekt erstellt wurde, müssen wir es öffnen:

Nun navigieren wir zu “APIs und Dienste” und dann oben unter dem Suchfenster auf “+ APIs und Dienste aktivieren”. Auf der sich nun öffnenden Seite suchen wir die Kachel zu “YouTube Data API v3” und wählen diese aus.

Anschließend klicken wir auf “aktivieren”.

Nachdem die API aktiviert wurde, klicken wir in der Seitenleiste auf der linken Seite auf “Anmeldedaten”

Anschließend wählen wir oben unter dem Suchfenster “+ Anmeldedaten erstellen” und dann “API Schlüssel”. Wichtig: Kopieren Sie den Schlüssel (ein langer Buchstaben-Zahlen-Code) und speichern Sie ihn an einem sicheren Ort. Teilen Sie den Schlüssel nicht mit anderen!

Installieren Sie anschließend in R das tuber-Paket, führen Sie den folgenden Befehl aus und fügen Sie den API-Schlüssel in das Pop-Up Fenster ein.

library(tuber)

tuber::yt_set_key()

Nun wählen wir zu Testzwecken ein Video aus unserem Wiedergabeverlauf-Datensatz aus. Dieses können wir auch zunächst über die URL im Browser öffnen, um zu schauen, welches es ist.

yt_data |>
  filter(str_detect(title, "thieves|Thieves|THIEVES")) |>
  head(1) |>
  pull(title_url)
[1] "https://www.youtube.com/watch?v=8AhrwThCfTY"

Mithilfe des tuber-Pakets können wir nun diverse Metadaten über das genannte Video laden. Dafür stellen wir der Funktion jeweils die Video-ID (das, was in der Video-URL nach https://www.youtube.com/watch?v= kommt) zur Verfügung. Diesen Schritt können wir später auch automatisieren und für viele Videos auf einmal durchführen. Für diese Übung schauen wir uns nun jedoch erstmal ein Video an.

# Statistiken laden
stats <-
  tuber::get_stats("8AhrwThCfTY", auth = "key") |>
  as_tibble()

# Details laden
details <-
  tuber::get_video_details("8AhrwThCfTY", auth = "key")

# Relevante Infos aus Liste auswählen
selected_details <-
  tibble(
    id = details$items[[1]]$id,
    published_at = lubridate::as_datetime(details$items[[1]]$snippet$publishedAt),
    channel_id = details$items[[1]]$snippet$channelId,
    channel_title = details$items[[1]]$snippet$channelTitle,
    title = details$items[[1]]$snippet$title,
    description = details$items[[1]]$snippet$description,
    thumbnail = details$items[[1]]$snippet$thumbnails$maxres$url,
    tags = str_flatten(unlist(details$items[[1]]$snippet$tags), collapse = ", ")
  )

# Kommentare laden
comments <-
  get_comment_threads(c(video_id = "8AhrwThCfTY"), auth = "key") |>
  as_tibble()
# Statistiken ansehen
stats
# A tibble: 1 × 5
  id          viewCount likeCount favoriteCount commentCount
  <chr>       <chr>     <chr>     <chr>         <chr>       
1 8AhrwThCfTY 122899    2730      0             86          
# Video-Details ansehen
selected_details
# A tibble: 1 × 8
  id    published_at        channel_id channel_title title description thumbnail
  <chr> <dttm>              <chr>      <chr>         <chr> <chr>       <chr>    
1 8Ahr… 2023-07-11 21:28:15 UCKoafhJ9… BBCRadio1VEVO Noth… "Nothing B… https://…
# ℹ 1 more variable: tags <chr>
# Thumbnail-URL und Tags ansehen
selected_details |>
  select(thumbnail, tags)
# A tibble: 1 × 2
  thumbnail                                            tags                     
  <chr>                                                <chr>                    
1 https://i.ytimg.com/vi/8AhrwThCfTY/maxresdefault.jpg Nothing But Thieves, Ove…
# Kommentare ansehen
comments
# A tibble: 75 × 13
  channelId                videoId    textDisplay textOriginal authorDisplayName
  <chr>                    <chr>      <chr>       <chr>        <chr>            
1 UCKoafhJ9dkAWaEvlXCiBBwA 8AhrwThCf… "Proving t… Proving tha… @FastRuffneck    
2 UCKoafhJ9dkAWaEvlXCiBBwA 8AhrwThCf… "he ate th… he ate this… @vante8148       
3 UCKoafhJ9dkAWaEvlXCiBBwA 8AhrwThCf… "Very nice… Very nice🥰🥰… @juliequinn2668  
4 UCKoafhJ9dkAWaEvlXCiBBwA 8AhrwThCf… "Conor&#39… Conor's voi… @lparry6875      
5 UCKoafhJ9dkAWaEvlXCiBBwA 8AhrwThCf… "<a href=\… 2:12 I'm ju… @Nata83689       
# ℹ 70 more rows
# ℹ 8 more variables: authorProfileImageUrl <chr>, authorChannelUrl <chr>,
#   authorChannelId.value <chr>, canRate <lgl>, viewerRating <chr>,
#   likeCount <dbl>, publishedAt <dttm>, updatedAt <dttm>
# Drei Kommentare testweise ansehen
comments |>
  head(3) |>
  pull(textOriginal)
[1] "Proving that every track should be awesome when stripped back 💙"
[2] "he ate this fckn mic I love him so much I fckn love this band"   
[3] "Very nice🥰🥰🥰🥰🥰"                                             
# Wie viele Herzchen kommen in allen Kommentaren zusammen vor?
str_count(comments$textOriginal, "❤") |> sum()
[1] 32

Weitere Metadaten können wir beispielsweise über das Kommandozeilen-Tool yt-dlp herunterladen und mittels whisper-ctranslate2 transkribieren. Weitere Informationen dazu finden Sie in der Dokumentation des CCS-Track Inhaltsanalysekurses hier. Anschließend können wir diese Inhalte auch automatisiert Inhaltsanalysieren, siehe hier.

Hausaufgabe

  1. Laden Sie Ihren eigenen YouTube-Verlauf und finden Sie heraus, wie weit der Wiedergabeverlauf in die Vergangenheit reicht (d.h., wann haben Sie das “älteste” Video im Datensatz geschaut)?

  2. An welchem Wochentag schauen Sie am meisten YouTube?

  3. Laden Sie die Kommentare zu einem Video aus ihrem Wiedergabeverlauf herunter und zählen Sie aus, wie häufig ein bestimmtes Wort darin vorkommmt.