TidyTuesday
    • About TidyTuesday
    • Datasets
      • 2025
      • 2024
      • 2023
      • 2022
      • 2021
      • 2020
      • 2019
      • 2018
    • Useful links

    On this page

    • Country Music Lyrics
      • The Data
      • How to Participate
        • PydyTuesday: A Posit collaboration with TidyTuesday
      • Data Dictionary
        • country_lyrics.csv
        • top_all_writers.csv
        • top_primary_writers.csv
        • top_producers.csv
      • Cleaning Script

    Country Music Lyrics

    This week we’re exploring Country Music Lyrics. The dataset comes from Grady Smith’s investigation into some stereotypes associated with this music genre.

    Here’s an excerpt from his video, “Every country song has these lyrics. Right?”, where he discusses his findings:

    Today’s video is a DEEP DIVE into the world of country music, and I’m determined to figure out if the stereotypes people have about modern country songwriting are actually true. Is it REALLY all about beer and trucks and girls and blue jeans? Are all the lyrics REALLY the same? To find out, I maintained a spreadsheet of every country song that has reached the Top 30 of Billboard’s Country Airplay chart for the past six years (2014-2019) and then crunched a whole lot of data.

    Dana Gibbon created this notebook that summarized and visualised some insights from the data.

    Some questions you can answer:

    • Is country radio run by a small circle of hitmakers?
    • How has the country ‘vocabulary’ shifted over time?

    Thank you to Jake Kaupp for suggesting this dataset.

    Thank you to Ntobeko Sosibo for curating this week’s dataset.

    The Data

    # Using R
    # Option 1: tidytuesdayR R package 
    ## install.packages("tidytuesdayR")
    
    tuesdata <- tidytuesdayR::tt_load('2026-08-25')
    ## OR
    tuesdata <- tidytuesdayR::tt_load(2026, week = 34)
    
    country_lyrics <- tuesdata$country_lyrics
    top_all_writers <- tuesdata$top_all_writers
    top_primary_writers <- tuesdata$top_primary_writers
    top_producers <- tuesdata$top_producers
    
    # Option 2: Read directly from GitHub
    
    country_lyrics <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/country_lyrics.csv')
    top_all_writers <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/top_all_writers.csv')
    top_primary_writers <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/top_primary_writers.csv')
    top_producers <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/top_producers.csv')
    # Using Python
    # Option 1: pydytuesday python library
    ## pip install pydytuesday
    
    import pydytuesday
    
    # Download files from the week, which you can then read in locally
    pydytuesday.get_date('2026-08-25')
    
    # Option 2: Read directly from GitHub and assign to an object
    
    country_lyrics = pandas.read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/country_lyrics.csv')
    top_all_writers = pandas.read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/top_all_writers.csv')
    top_primary_writers = pandas.read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/top_primary_writers.csv')
    top_producers = pandas.read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/top_producers.csv')
    # Using Julia
    # Option 1: TidierTuesday.jl library
    ## Pkg.add(url="https://github.com/TidierOrg/TidierTuesday.jl")
    
    using TidierTuesday
    
    # Download datasets for the week, and load them as a NamedTuple of DataFrames
    data = tt_load("2026-08-25")
    
    # Option 2: Read directly from GitHub and assign to an object with TidierFiles
    
    country_lyrics = read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/country_lyrics.csv")
    top_all_writers = read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/top_all_writers.csv")
    top_primary_writers = read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/top_primary_writers.csv")
    top_producers = read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/top_producers.csv")
    
    # Option 3: Read directly from Github and assign without Tidier dependencies
    country_lyrics = CSV.read("https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/country_lyrics.csv", DataFrame)
    top_all_writers = CSV.read("https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/top_all_writers.csv", DataFrame)
    top_primary_writers = CSV.read("https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/top_primary_writers.csv", DataFrame)
    top_producers = CSV.read("https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-08-25/top_producers.csv", DataFrame)

    How to Participate

    • Explore the data, watching out for interesting relationships. We would like to emphasize that you should not draw conclusions about causation in the data. There are various moderating variables that affect all data, many of which might not have been captured in these datasets. As such, our suggestion is to use the data provided to practice your data tidying and plotting techniques, and to consider for yourself what nuances might underlie these relationships.
    • Create a visualization, a model, a Quarto report, a shiny app, or some other piece of data-science-related output, using R, Python, or another programming language.
    • Share your output and the code used to generate it on social media with the #TidyTuesday hashtag.
    • Submit your own dataset!

    PydyTuesday: A Posit collaboration with TidyTuesday

    • Exploring the TidyTuesday data in Python? Posit has some extra resources for you! Have you tried making a Quarto dashboard? Find videos and other resources in Posit’s PydyTuesday repo.
    • Share your work with the world using the hashtags #TidyTuesday and #PydyTuesday so that Posit has the chance to highlight your work, too!
    • Deploy or share your work however you want! If you’d like a super easy way to publish your work, give Connect Cloud a try.

    Data Dictionary

    country_lyrics.csv

    variable class description
    song character The title of the track.
    artist character The primary performing artist or band credited for the track.
    featuring character Guest or featured artists on the track. NA if solo performance.
    entered_top_30_in integer The date or month/year the track first entered the Top 30 Country Airplay chart.
    lyrics character Full text lyrics for the track.
    writers character Songwriters credited on the track (frequently multi-value / comma-separated).
    producer character Record producer(s) credited for the track (may contain multiple names separated by slashes/commas).
    rough_order integer Original entry index or sequence number assigned during data collection.
    rules_top_30_country_airplay double Original metadata / eligibility notes detailing chart inclusion rules (March 2014 – March 2017).

    top_all_writers.csv

    variable class description
    writer character Name of the songwriter.
    song_count integer Total number of songs in the dataset where this individual appears in the writing credits (including co-writes).

    top_primary_writers.csv

    variable class description
    writer character Name of the songwriter listed as the primary credit.
    song_count integer Total number of songs in the dataset where this individual is credited as a primary writer.

    top_producers.csv

    variable class description
    producer character Name of the record producer.
    song_count integer Total number of songs in the dataset produced or co-produced by this individual.

    Cleaning Script

    # Data provided by Grady Smith.
    
    # Getting the data ----
    library(tidyverse)
    library(openxlsx)
    
    # Extract the Spreadsheet ID from the Google Sheet URL
    # The full link is: https://drive.google.com/file/d/1lz-xpqufGggdPh4gUeIdYvtB2s8ePewn/view
    sheet_id <- "1lz-xpqufGggdPh4gUeIdYvtB2s8ePewn"
    
    # Construct the direct export URL
    export_url <- paste0(
      "https://docs.google.com/spreadsheets/d/",
      sheet_id,
      "/export?format=xlsx"
    )
    
    # Download to a temporary file
    temp_xlsx <- tempfile(fileext = ".xlsx")
    download.file(export_url, destfile = temp_xlsx, mode = "wb")
    
    # Read using openxlsx
    country_lyrics <- read.xlsx(temp_xlsx, sheet = 1) |>
      # Cleaning column names and drop empty column
      select(
        song = Song,
        artist = Artist,
        featuring = Featuring,
        entered_top_30_in = `Entered.Top.30.In:`,
        lyrics = Lyrics,
        writers = `Writers`,
        producer = `Producer`,
        rough_order = `Rough.Order`
      )
    writers_producers <- read.xlsx(temp_xlsx, sheet = 2)
    
    # Splitting the writers_producers table into the three categories ----
    
    # Table 1: Primary Writers Summary
    top_primary_writers <- writers_producers |>
      select(
        writer = Writer,
        song_count = `#.songs`
      ) |>
      drop_na()
    
    # Table 2: All Co-Writers Summary
    top_all_writers <- writers_producers |>
      select(
        writer = Writers,
        song_count = `#.Songs`
      ) |>
      drop_na()
    
    # Table 3: Record Producers Summary
    top_producers <- writers_producers |>
      select(producer = Producers, song_count = `#.Songsss`) |>
      drop_na()