# A tibble: 8 × 5
GradeGroup TestType n_student mean_PAE mean_IE
<chr> <chr> <int> <dbl> <dbl>
1 Foundation A BNL0-20 1206 0.165 19.7
2 Foundation A UNL0-20 1221 0.207 12.5
3 Foundation B BNL0-20 1128 0.166 19.8
4 Foundation B UNL0-20 1153 0.204 14.5
5 Year 1A BNL0-100 1260 0.140 25.4
6 Year 1A UNL0-20 1254 0.119 6.87
7 Year 1B BNL0-100 1050 0.138 11.0
8 Year 1B UNL0-20 1063 0.126 7.41
Generate wide format
Code
# 1. Build one big wide table, keeping GradeGroup & TestType as keyswide_by_group_test <- nl_scored %>%# extract the 3-digit item suffixmutate(item =str_extract(`Question Identifier`, "\\d{3}$")) %>%# keep only the columns we needselect(Identifier, GradeGroup, `Test Identifier`, item, Number_clicked, `Answer Duration`, PAE) %>%# pivot to wide, with one block of columns per itempivot_wider(names_from = item,values_from =c(Number_clicked, `Answer Duration`, PAE),names_glue ="{.value}_item{item}" )# 2. Split into a list by GradeGroup × Test Identifierwide_list <- wide_by_group_test %>%group_by(GradeGroup, `Test Identifier`) %>%group_split(.keep =TRUE)# capture matching sheet namessheet_names <- wide_by_group_test %>%distinct(GradeGroup, `Test Identifier`) %>%mutate(sheet =glue("{GradeGroup}_{`Test Identifier`}")) %>%pull(sheet)# 3. Create workbook and add each sub‐wide table as its own sheetwb <-createWorkbook()walk2(wide_list, sheet_names, function(df, sh) {addWorksheet(wb, sh)writeData(wb, sh, df)})# 4. Finally add the master answer‐key on its own sheetaddWorksheet(wb, "Answer Key")writeData(wb, "Answer Key", answer_key_df)# 5. Save the filesaveWorkbook( wb,file ="numb_line_by_grade_test.xlsx",overwrite =TRUE)
6.2 Distribution of response per item
Code
plot_response <-function(df, bins) { df <- df %>%mutate(facet =paste0(`Question Identifier`, " (", `Answer Key`, ")"))## -- build the plot *first* (we'll grab its stats in a moment) base_plot <-ggplot( df,aes(Number_clicked, group = facet) # one histogram per item ) +geom_histogram(aes(y =after_stat(count /sum(count))),bins = bins,boundary =0,colour ="grey20", fill ="grey80" ) +geom_vline(aes(xintercept =`Answer Key`), colour ="red") +facet_wrap(~ facet, scales ="free_y", ncol =4) +scale_y_continuous(labels =percent_format(accuracy =0.1)) +labs(x ="Number clicked",y ="Percent of students",caption ="Red line = target number" ) +theme_bw()## -- extract max proportion across all facets stats <-ggplot_build(base_plot)$data[[1]] max_prop <-max(stats$y, na.rm =TRUE) # highest bar y_limit <- max_prop *1.05# +5 % head-room## -- return the finished plot with a universal y-limit base_plot +coord_cartesian(ylim =c(0, y_limit), clip ="off")}bins_map <-c("BNL0-100"=25,"BNL0-20"=21,"UNL0-20"=34)unique(nl_scored$TestType) %>%walk(function(tt) { df_probe <- nl_scored %>%filter(TestType == tt) bins <- bins_map[tt] p <-plot_response(df_probe, bins)print(p) ggsave(filename =file.path(probe_dir, glue("response_dist_{tt}.png")),plot = p,width =12, height =8, dpi =300, units ="in" ) })