Skip to content

Instantly share code, notes, and snippets.

@benmarwick
Last active October 2, 2023 05:53
Show Gist options
  • Select an option

  • Save benmarwick/c5ac05186caa30f896154dc122c0608c to your computer and use it in GitHub Desktop.

Select an option

Save benmarwick/c5ac05186caa30f896154dc122c0608c to your computer and use it in GitHub Desktop.
Randomly assign students into seminar reading groups of equal sizes, different groups each week
# get canvas gradebook as CSV...
library(tidyverse)
students <-
readr::read_csv("2023-10-01T2053_Grades-ARCHY_482_A.csv") %>%
# exclude test student
filter(!is.na(`SIS User ID`)) %>%
select(Student) %>%
as.data.frame()
# add one column per seminar to hold the group assignments
seminar_names <- str_glue('seminar_{1:10}_reading_group')
students[, seminar_names] <- NA
# randomly allocate students into n groups
x <- 1:nrow(students) # how many students do we have?
# we have this many students
length(x)
# if we want 4 students per group, how many groups?
students_per_group <- 4
n <- length(x) / students_per_group
group_numbers <- cut_number(x, n, labels = FALSE)
# make a dataframe of group assignments for each seminar
students_seminar_groupings <-
students %>%
mutate(across(starts_with('seminar'),
~sample(group_numbers)))
# check that each group has about the same number of people each week
checks <-
map_dfc(seminar_names,
~students_seminar_groupings %>%
group_by(!!rlang::sym(.x)) %>%
tally()
)
# write to CSV
write_csv(students_seminar_groupings,
"students_seminar_groupings.csv")
# for week by week, two groups per seminar:
# 1. sort by reading group number (Data -> sort by range)
# 2. create a column "seminar_1_mixed_group"
# 3. in the 'seminar_1_mixed_group' column, enter a repeating sequence of 1 -> n, where n is the number of groups (in this case, 4)
# 4. sort by student name so they can easily find their numbers by browsing
# 5. apply formatting to get alternating row colours (Format -> alternating colours)
# how to randomly assign discussion group leaders for each group?
seminar_reading_assignments <-
vector("list", length = length(seminar_names))
names(seminar_reading_assignments) <- seminar_names
for(i in seminar_names){
seminar_reading_assignments[[i]] <-
students_seminar_groupings %>%
select(Student, !!rlang::sym(i)) %>%
arrange(!!rlang::sym(i)) %>%
group_by(!!rlang::sym(i)) %>%
mutate(!!paste0(i, "_leader") := replace(!!rlang::sym(i),
sample(1:students_per_group, 1),
paste0(!!rlang::sym(i),
"L"))) %>%
mutate(seminar_mixed_group = 1:n()) %>%
group_by(seminar_mixed_group) %>%
arrange(seminar_mixed_group) %>%
mutate(seminar_mixed_group_leader = replace(seminar_mixed_group,
sample(1:students_per_group, 1),
paste0(seminar_mixed_group, "L"))) %>%
arrange(Student) %>%
ungroup() %>%
dplyr::select(-c(seminar_mixed_group,
!!rlang::sym(i)))
}
map2(seminar_reading_assignments,
seminar_names,
~write_csv(.x,
file = paste0(.y, ".csv")))
# check to see if the distribution is roughly fair
map2(seminar_reading_assignments,
paste0(seminar_names, "_leader"),
~ rename(all_of(.), "seminar_reading_group_leader" = .y)) %>%
bind_rows(., .id = "seminar") %>%
mutate(leader = case_when(
str_detect(seminar_reading_group_leader, "L") ~ TRUE,
str_detect(seminar_mixed_group_leader, "L") ~ TRUE
)) %>%
group_by(Student) %>%
tally(leader) %>%
ggplot() +
aes(Student, n) +
geom_col() +
coord_flip()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment