{
"$type": "site.standard.document",
"content": "---\ntitle: \"Pulling apart Zoom attendance csv dumps in tidy R\"\ndescription: \"A quick tidyverse R script for parsing Zoom attendance CSVs and visualising\n per-participant call duration with ggplot2.\"\ntags:\n - dev\n---\n\nMy team ran some Zoom training last week and today I needed to figure out who\nactually attended across all the days, and for how long.\n\nZoom can give you a csv dump of all attendees but doesn't provide the\naggregations I was after, so I hacked up a little script (in\n[tidy R](https://www.tidyverse.org)) to do it. If you ever want to do something\nsimilar, feel free to use it ([MIT Licence](https://mit-license.org)).\n\n```r\nread_zoom_attendance_csv = function(filename){\n read_csv(filename, show_col_types = FALSE) %>%\n # I only needed the date, not the actual start time, so I didn't bother parsing\n # the full datetime + timezone string that Zoom gives\n mutate(date = parse_date(str_sub(`Join Time`, end = 10), format = \"%m/%d/%Y\")) %>%\n # this isn't necessary, but I like shorter column names\n rename(name = `Name (Original Name)`, email = `User Email`, duration = `Duration (Minutes)` ) %>%\n # I'm only intrested in these columns\n select(name, email, date, duration) %>%\n # this isn't necessary, but handy if individuals have signed in with\n # slightly different names on different days (requires eyeballing the data)\n mutate(name = recode(name,\n \"JS\" = \"Joanna Smith\",\n \"Louise\" = \"Louise Jones\"\n}\n```\n\nThen you can read the Zoom csv file like so:\n\n```r\ndf = read_zoom_attendance_csv(\"zoom-call.csv\")\n```\n\nAnd to visualise in [ggplot2](https://ggplot2.tidyverse.org) (which was my\nreason for using R in the first place) you could try something like:\n\n```r\ndf %>%\n group_by(name, date) %>%\n # this was the key summarisation I was after - total time\n # in-call across multiple connects/re-connects\n summarise(duration = sum(duration)) %>%\n ungroup() %>%\n ggplot(aes(name, duration)) +\n geom_col() +\n coord_flip() +\n facet_wrap(~date, nrow = 1) +\n labs(\n title = \"Zoom call attendance\",\n x = \"participant name\",\n y = \"duration on the call (minutes)\"\n )\n```\n\nEnjoy!\n",
"createdAt": "2026-05-13T23:14:49.074Z",
"description": "A quick tidyverse R script for parsing Zoom attendance CSVs and visualising per-participant call duration with ggplot2.",
"path": "/blog/2022/05/23/pulling-apart-zoom-attendance-csv-dumps-in-tidy-r",
"publishedAt": "2022-05-23T00:00:00.000Z",
"site": "at://did:plc:tevykrhi4kibtsipzci76d76/site.standard.publication/self",
"tags": [
"dev"
],
"textContent": "A quick tidyverse R script for parsing Zoom attendance CSVs and visualising per-participant call duration with ggplot2.",
"title": "Pulling apart Zoom attendance csv dumps in tidy R"
}