Skip to content

Instantly share code, notes, and snippets.

@sebastiansauer
Created May 20, 2016 08:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sebastiansauer/4da6dc87591e54ceabbff37a489404b1 to your computer and use it in GitHub Desktop.
Save sebastiansauer/4da6dc87591e54ceabbff37a489404b1 to your computer and use it in GitHub Desktop.
This gist provides a convenience function for a typical teacher duty: grade exams.
# Exam grading, as a convenience function for teachers
# Sebastian Sauer
# Stand: 2016-05-20
# need to be installed upfront with "install.packages()"
library(ggplot2)
library(car)
library(tidyr)
library(stringr)
library(magrittr)
library(gridExtra)
library(dplyr)
library(DT)
# solution vector(s)------------------------------------------------------------
# solution of my exam 01
solution_1 <-
c(F, F, F, F, F, # 1 - 5
T, F, T, F, F, # 6 - 10
T, T, F, T, T, # 11 - 15
T, F, F, T, F, # 16 - 20
F, T, F, T, F, # 21 - 25
F, F, F, F, T, # 26 - 30
F, F, T, F, T, # 31- 35
F, F, F, T, F) # 36 - 40
# solution of my exam 02
solution_2 <- c(T, T, T, T, F, # 1 - 5
F, F, F, F, T, # 6 - 10
T, T, F, T, T, # 11 - 15
T, T, T, T, F, # 16 - 20
F, T, T, F, T, # 21 - 25
F, F, F, T, F, # 26 - 30
T, T, F, T, T, # 31 - 35
F, T, T, T, F # 36 - 40
)
# grading scheme ---------------------------------------------------------------
# please adjust to your scheme
# note that length of grading+1 must equal the length of the solution vector
grading <- c(5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, #10 (starting from zero)
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, #20
5, 5, 5, 5, 4, 4, 4, 4, 4, 3, #30
3, 3, 3, 2, 2, 2, 2, 1, 1, 1) #40
# load data --------------------------------------------------------------------
# I used a google form for the exam. Works great.
# Export your data ax a CSV spreadsheet from google docs.
# either like this:
#pk <- read.csv(file.choose())
# or define path and file name:
path_data <- "~/Downloads"
data_file <- "pk_inf.csv"
setwd(path_data)
pk <- read.csv(file = data_file, header = TRUE)
# grading function -------------------------------------------------------------
# function for scoring, and matching scores to grades
grade_exam <- function(exam_data, solution_vector, grading_scheme, ID){
# arguments:
# exam_data: dataframe n*i with responses; n rows, i items
# it is assumed that all questions are binary; Either correct or false.
# solution_vector: Vector with correct solutions (logical vector)
# grading_scheme: matching scheme for points --> grade (numeric vector)
# ID: IDs of students/test takers, so to know who has which grade
# returns:
# score: vector
# grade: integer
# rename (shorten) variables, as google docs variable names are verbose
items <- colnames(exam_data)
colnames(exam_data) <- paste("i_", 1:ncol(exam_data), sep = "")
# Recode responses to TRUE/FALSE: "Richtig" --> TRUE, "Falsch" --> FALSE
# please adjust the responses as spit out by your form here!
# I used German responses, you might use another language
exam_data <- exam_data %>%
mutate_each(funs(recode(.,
"'Richtig' = TRUE;
'Falsch' = FALSE;
else = NA")), 1:ncol(exam_data)) %>%
mutate_each(funs(as.logical(.)), 1:ncol(exam_data))
# Match responses to solution and tally up the score
exam_data$score <- apply(exam_data, 1,
function(x) sum(x == solution_vector, na.rm = T))
# add ID variable to dataframe
exam_data$ID <- ID
# Delete rows with score == 0, as these are mainly dummy data
exam_data <- exam_data %>%
filter(!(score == 0))
# match scores to grade (assign grades)
exam_data$grade <- grading_scheme[exam_data$score]
# return scores and grade only
exam_data <- exam_data %>%
select(ID, score, grade)
return(exam_data)
}
# now grade the test responses -------------------------------------------------
exam1 <- grade_exam(exam_data = select(pk_inf, 2:41),
solution_vector = solution_2,
grading_scheme = grading,
ID = pk_inf[, 42])
# plot grades
exam1 %>%
ggplot(aes(x = grade)) %>%
add(geom_histogram())
# plot ID alongside with score and grade
dev.off()
exam1 %>%
arrange(ID) %>%
grid.table()
# plot interactive table
exam1 %>%
dplyr::filter(!is.na(ID), !(ID == "")) %>%
arrange(ID) %>% datatable(., options = list(pagelength = 20))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment