::opts_chunk$set(eval = FALSE) knitr
With the goal of learning my students’ names faster, I wrote an R script that will convert a roster (“People” in a Canvas course) to a gt
table for later offline use.
Setup
In your Canvas course, go to People
, right-click on the roster, and click “Save Page As”
- be sure to save the “complete” web page (this creates a folder with all of the students’ pictures)
- place the also downloaded HTML file into the folder
- place this code script into the folder
# change this file name as needed
<- "Course Roster S23-BIO 018 01.htm"
HTML_file_name
library("gt")
library("gtExtras")
library("rvest")
library("tidyverse")
Roster table
https://www.r-bloggers.com/2020/04/scrape-html-table-using-rvest/
<- read_html(HTML_file_name)
content <- content |> html_table(fill = TRUE)
tables <- tables[[1]]
roster_table
<- roster_table |>
roster_df select(Name, Section) |>
mutate(discussion_tag = str_extract(Section, "Discussion-\\d\\dD")) |>
separate(discussion_tag, sep = "-", into = c("disregard", "discussion_section")) |>
select(Name, discussion_section) |>
# remove instructor of record
filter(!is.na(discussion_section))
Images
https://community.rstudio.com/t/scraping-images-from-the-web/133239
<- content |> html_elements("img")
image_urls <- length(image_urls)
num_images
<- data.frame(html_raw = rep(NA, num_images))
image_df_raw for(img in 1:num_images){
$html_raw[img] <- as.character(image_urls[[img]])
image_df_raw
}
<- image_df_raw |>
image_df
# skip first two images?
slice(3:n()) |>
# roundabout because some people's names have more than 2 words
separate(col = "html_raw", sep = "alt=",
into = c("part1", "part2")) |>
separate(col = "part1", sep = " ", into = c("tag1", "src")) |>
separate(col = "src", sep = "/", into = c("stem", "profile_picture")) |>
separate(col = "part2", sep = " aria", into = c("student_name", "tag2")) |>
select(profile_picture, student_name)
# remove quotation marks
$profile_picture <- str_replace_all(image_df$profile_picture, "\"", "")
image_df$student_name <- str_replace_all(image_df$student_name, "\"", "") image_df
Merge
<- roster_df |>
roster_df left_join(image_df, by = c("Name" = "student_name")) |>
select(profile_picture, Name, discussion_section)
gt
https://jthomasmock.github.io/gtExtras/reference/gt_img_rows.html
<- roster_df |>
roster_gt gt() |>
gt_img_rows(columns = profile_picture, img_source = "local")
gtsave(roster_gt, "roster.png")