#lets first load the files
if (Sys.info()["sysname"] == "Windows"){
}else{
#F23
m1f23 = read.csv("~/Teaching/Grades_and_SRT/Fall2023/m1.csv",header = TRUE)
m2f23 = read.csv("~/Teaching/Grades_and_SRT/Fall2023/m2.csv",header = TRUE)
m3f23 = read.csv("~/Teaching/Grades_and_SRT/Fall2023/m3.csv",header = TRUE)
m4f23 = read.csv("~/Teaching/Grades_and_SRT/Fall2023/m4.csv",header = TRUE)
gradesf23 = read.csv("~/Teaching/Grades_and_SRT/Fall2023/chem1331_f23_grades_canvas.csv",header = TRUE)
#F22
m1f22 = read.csv("~/Teaching/Grades_and_SRT/Fall2022/m1.csv",header = TRUE)
m2f22 = read.csv("~/Teaching/Grades_and_SRT/Fall2022/m2.csv",header = TRUE)
m3f22 = read.csv("~/Teaching/Grades_and_SRT/Fall2022/m3.csv",header = TRUE)
m4f22 = read.csv("~/Teaching/Grades_and_SRT/Fall2022/m4.csv",header = TRUE)
gradesf22 = read.csv("~/Teaching/Grades_and_SRT/Fall2022/chem1331_f22_grades_canvas.csv",header = TRUE)
#F21
m1f21 = read.csv("~/Teaching/Grades_and_SRT/Fall2021/milestone1.csv",header = TRUE)
m2f21 = read.csv("~/Teaching/Grades_and_SRT/Fall2021/milestone2.csv",header = TRUE)
m3f21 = read.csv("~/Teaching/Grades_and_SRT/Fall2021/milestone3.csv",header = TRUE)
m4f21 = read.csv("~/Teaching/Grades_and_SRT/Fall2021/milestone4.csv",header = TRUE)
#ex1 = read.csv("~/Teaching/Grades_and_SRT/Fall2021/Exam_1_scores.csv",header = TRUE)
#ex2 = read.csv("~/Teaching/Grades_and_SRT/Fall2021/Exam_2_scores.csv",header = TRUE)
gradesf21 = read.csv("~/Teaching/Grades_and_SRT/Fall2021/chem1331_f21_finalgrades.csv",header = TRUE)
gradesf21 = read.csv("~/Teaching/Grades_and_SRT/Fall2021/chem1331_f21_finalgrades_canvas.csv",header = TRUE)
#demo21 = read.csv("~/Teaching/Grades_and_SRT/Fall2021/")
#use this file to compare among years
videof21 = read.csv("~/Teaching/Grades_and_SRT/Fall2021/videowatching_resultsf21.csv",header = TRUE)
#this video analytics has all the videos of the course
videof21_all = read.csv("~/Teaching/Grades_and_SRT/Fall2021/videowatchingAnalytics.csv",header = TRUE)
#m1practicef21 = read.csv("~/Teaching/Grades_and_SRT/Fall2021/milestone1_practice.csv",header = TRUE)
#m2practicef21 = read.csv("~/Teaching/Grades_and_SRT/Fall2021/milestone2_practice.csv",header = TRUE)
#m3practicef21 = read.csv("~/Teaching/Grades_and_SRT/Fall2021/milestone3_practice.csv",header = TRUE)
#m4practicef21 = read.csv("~/Teaching/Grades_and_SRT/Fall2021/milestone4_practice.csv",header = TRUE)
#F19
m1f19 = read.csv("~/Teaching/Grades_and_SRT/Fall2019/CHEM1331/milestone1.csv",header = TRUE)
m2f19 = read.csv("~/Teaching/Grades_and_SRT/Fall2019/CHEM1331/milestone2.csv",header = TRUE)
m3f19 = read.csv("~/Teaching/Grades_and_SRT/Fall2019/CHEM1331/milestone3.csv",header = TRUE)
m4f19 = read.csv("~/Teaching/Grades_and_SRT/Fall2019/CHEM1331/milestone4.csv",header = TRUE)
gradesf19 = read.csv("~/Teaching/Grades_and_SRT/Fall2019/CHEM1331/chem1331f19_gradebook.csv",header = TRUE)
#demo19 = read.csv("~/Teaching/Grades_and_SRT/Fall2019/CHEM1331/DISCOVER_chem1331_f19.csv")
videof19 = read.csv("~/Teaching/Grades_and_SRT/Fall2019/CHEM1331/videowatching_resultsf19.csv",header = TRUE)
#m1practicef19 = read.csv("~/Teaching/Grades_and_SRT/Fall2019/CHEM1331/milestone1_practice.csv",header = TRUE)
#m2practicef19 = read.csv("~/Teaching/Grades_and_SRT/Fall2019/CHEM1331/milestone2_practice.csv",header = TRUE)
#m3practicef19 = read.csv("~/Teaching/Grades_and_SRT/Fall2019/CHEM1331/milestone3_practice.csv",header = TRUE)
#m4practicef19 = read.csv("~/Teaching/Grades_and_SRT/Fall2019/CHEM1331/milestone4_practice.csv",header = TRUE)
gradesf18 = read.csv("~/Teaching/Grades_and_SRT/Fall2018/chem1331_f18.csv",header = TRUE)
gradesf18mood = read.csv("~/Teaching/Grades_and_SRT/Fall2018/c1_f18_moodle_gradebook.csv",header = TRUE)
m1f18 = read.csv("~/Teaching/Grades_and_SRT/Fall2018/milestone1.csv",header = TRUE)
videof18 = read.csv("~/Teaching/Grades_and_SRT/Fall2018/videowatching_resultsf18.csv",header = TRUE)
}
As you will see below, since we’re using different assignments, the grade distribution is not comparable. The main takeaways are
nf18 = length(gradesf18$Student)
nf19 = length(gradesf19$Student)
nf21 = length(gradesf21$Student)
nf22 = length(gradesf22$Student)
nf23 = length(gradesf23$Student)
#revmove D-
gradesf18$Unposted.Final.Grade = gsub('D-','D', gradesf18$Unposted.Final.Grade)
gradesf19$Unposted.Final.Grade = gsub('D-','D', gradesf19$Unposted.Final.Grade)
gradesf21$Unposted.Final.Grade = gsub('D-','D', gradesf21$Unposted.Final.Grade)
gradesf22$Unposted.Final.Grade = gsub('D-','D', gradesf22$Unposted.Final.Grade)
gradesf23$Unposted.Final.Grade = gsub('D-','D', gradesf23$Unposted.Final.Grade)
#remove column to avoid confusion
gradesf18$Final.Grade = NULL
gradesf19$Final.Grade = NULL
gradesf21$Final.Grade = NULL
gradesf22$Final.Grade = NULL
gradesf23$Final.Grade = NULL
gradesf18$simpleLetter = gsub('\\+','',
gsub('-','',gradesf18$Unposted.Current.Grade))
gradesf19$simpleLetter = gsub('\\+','',
gsub('-','',gradesf19$Unposted.Current.Grade))
gradesf21$simpleLetter = gsub('\\+','',
gsub('-','',gradesf21$Unposted.Current.Grade))
gradesf22$simpleLetter = gsub('\\+','',
gsub('-','',gradesf22$Unposted.Current.Grade))
gradesf23$simpleLetter = gsub('\\+','',
gsub('-','',gradesf23$Unposted.Current.Grade))
allLetters = as.data.frame.matrix( rbind(
table(gradesf18$Unposted.Final.Grade)/length(gradesf18$Unposted.Final.Grade)*100,
table(gradesf19$Unposted.Final.Grade)/length(gradesf19$Unposted.Final.Grade)*100,
table(gradesf21$Unposted.Final.Grade)/length(gradesf21$Unposted.Final.Grade)*100,
table(gradesf22$Unposted.Final.Grade)/length(gradesf22$Unposted.Final.Grade)*100,
table(gradesf23$Unposted.Final.Grade)/length(gradesf23$Unposted.Final.Grade)*100
#table(gradesf21$LetterGrade)/length(gradesf21$LetterGrade)*100
) )
allStats = as.data.frame.matrix( rbind(
summary(gradesf18$Final.Score),
summary(gradesf19$Final.Score),
summary(gradesf21$Final.Score),
summary(gradesf22$Final.Score),
summary(gradesf23$Final.Score)
))
#allStats = cbind(allStats,allLetters)
allStats = cbind(Nstudents = c(
length(gradesf18$Student),
length(gradesf19$Student),
length(gradesf21$Student),
length(gradesf22$Student),
length(gradesf23$Student)
),allStats)
row.names(allStats) = c("Fall18","Fall19","Fall21","Fall22","Fall23")
row.names(allLetters) = c("Fall18","Fall19","Fall21","Fall22","Fall23")
knitr::kable(allLetters,caption = "Final Grade Letter Percents",digits = 1)
A | A- | B | B- | B+ | C | C- | C+ | D | F | |
---|---|---|---|---|---|---|---|---|---|---|
Fall18 | 28.7 | 22.1 | 14.9 | 6.6 | 16.0 | 2.8 | 1.1 | 2.8 | 2.2 | 2.8 |
Fall19 | 9.3 | 14.3 | 15.4 | 17.0 | 20.9 | 5.5 | 3.3 | 8.8 | 3.3 | 2.2 |
Fall21 | 21.0 | 16.9 | 13.8 | 4.6 | 17.4 | 4.1 | 6.2 | 6.7 | 5.1 | 4.1 |
Fall22 | 17.3 | 12.5 | 14.9 | 14.9 | 19.2 | 5.3 | 4.3 | 7.7 | 0.5 | 3.4 |
Fall23 | 21.2 | 25.8 | 11.3 | 8.6 | 11.9 | 5.3 | 4.6 | 6.6 | 0.7 | 4.0 |
Nstudents | Min. | 1st Qu. | Median | Mean | 3rd Qu. | Max. | |
---|---|---|---|---|---|---|---|
Fall18 | 181 | 26.8 | 85.4 | 90.0 | 87.5 | 93.6 | 97.8 |
Fall19 | 182 | 26.2 | 76.8 | 81.2 | 80.2 | 85.7 | 94.6 |
Fall21 | 195 | 20.1 | 79.7 | 87.3 | 84.0 | 92.3 | 99.1 |
Fall22 | 208 | 37.4 | 80.5 | 86.2 | 84.6 | 91.8 | 97.9 |
Fall23 | 151 | 18.6 | 81.8 | 89.2 | 85.7 | 92.6 | 97.9 |
The statistics shown above are only the students who were still registered at the end of the semester. Some students withdrew from the course, we are going to use the number of students who took milestone 1 as the number of students who started to compare with the number of students who finished.
Pay attention to this high number of withdrawls. This means that the overall grade average would have been much lower if all these people who dropped stayed until the end.
gradesf18[which(gradesf18$Exam.1..335345.==0),]$Exam.1..335345. = NA
gradesf21[which(gradesf21$Exam..1..2161998.==0),]$Exam..1..2161998. = NA
gradesf21[which(gradesf21$Exam..1..2161998.=="EX"),]$Exam..1..2161998. = NA
gradesf21$Exam..1..2161998. = as.numeric(gradesf21$Exam..1..2161998.)/25*100
gradesf22[which(gradesf22$Open.Ended.Exam..1..2592814. == 0),]$Open.Ended.Exam..1..2592814. = NA
gradesf22$Open.Ended.Exam..1..2592814. = as.numeric(gradesf22$Open.Ended.Exam..1..2592814.)/25*100
#gradesf23[which(gradesf23$Open.Ended.Exam..1..3262287. == 0),]$Open.Ended.Exam..1..3262287. = NA
gradesf23$Open.Ended.Exam..1..3262287. = as.numeric(gradesf23$Open.Ended.Exam..1..3262287.)/25*100
allStats = as.data.frame.matrix( rbind(
summary(gradesf18$Exam.1..335345.),
summary(gradesf19$Open.Ended.Written.Exam.1..816325.),
summary(gradesf21$Exam..1..2161998.),
summary(gradesf22$Open.Ended.Exam..1..2592814.),
summary(gradesf23$Open.Ended.Exam..1..3262287.)
))
row.names(allStats) = c("Fall18","Fall19","Fall21","Fall22","Fall23")
allStats$`NA's` = NULL
knitr::kable(allStats,caption = "Exam 1 Statistics",digits = 1)
Min. | 1st Qu. | Median | Mean | 3rd Qu. | Max. | |
---|---|---|---|---|---|---|
Fall18 | 16.0 | 52.0 | 66.0 | 64.2 | 76.0 | 96.0 |
Fall19 | 13.1 | 44.3 | 58.3 | 57.4 | 72.3 | 95.2 |
Fall21 | 12.0 | 68.0 | 81.2 | 78.4 | 92.2 | 100.0 |
Fall22 | 10.0 | 41.0 | 58.0 | 57.0 | 74.0 | 100.0 |
Fall23 | 8.0 | 48.0 | 65.0 | 64.9 | 86.0 | 98.0 |
#EXAM 2
gradesf18[which(gradesf18$Exam.2..358394.==0),]$Exam.2..358394. = NA
gradesf19[which(gradesf19$Open.Ended.Exam.2..836125.==0),]$Open.Ended.Exam.2..836125. = NA
gradesf21[which(gradesf21$Exam..2..2171776.==0),]$Exam..2..2171776. = NA
gradesf21$Exam..2..2171776. = as.numeric(gradesf21$Exam..2..2171776.)/25*100
gradesf22[which(gradesf22$Open.Ended.Exam..2..2592815. == 0),]$Open.Ended.Exam..2..2592815. = NA
#out of 26 of all numbers :)
gradesf22$Open.Ended.Exam..2..2592815. = as.numeric(gradesf22$Open.Ended.Exam..2..2592815.)/26*100
gradesf23[which(gradesf23$Open.Ended.Exam..2..3262288. == 0),]$Open.Ended.Exam..2..3262288. = NA
gradesf23$Open.Ended.Exam..2..3262288. = as.numeric(gradesf23$Open.Ended.Exam..2..3262288.)/25*100
allStats = as.data.frame.matrix( rbind(
summary(gradesf18$Exam.2..358394.),
summary(gradesf19$Open.Ended.Exam.2..836125.),
summary(gradesf21$Exam..2..2171776.),
summary(gradesf22$Open.Ended.Exam..2..2592815.),
summary(gradesf23$Open.Ended.Exam..2..3262288.)
))
row.names(allStats) = c("Fall18","Fall19","Fall21","Fall22","Fall23")
#allStats$`NA's` = NULL
knitr::kable(allStats,caption = "Exam 2 Statistics",digits = 1)
Min. | 1st Qu. | Median | Mean | 3rd Qu. | Max. | NA’s | |
---|---|---|---|---|---|---|---|
Fall18 | 19.0 | 59.5 | 75.0 | 70.5 | 84.0 | 98.0 | 5 |
Fall19 | 19.0 | 49.0 | 67.0 | 63.8 | 78.0 | 100.0 | 1 |
Fall21 | 9.0 | 51.4 | 65.4 | 63.6 | 78.3 | 98.5 | 2 |
Fall22 | 6.7 | 42.0 | 58.0 | 58.1 | 78.8 | 100.0 | 2 |
Fall23 | 6.0 | 43.2 | 60.0 | 58.6 | 76.0 | 94.0 | 1 |
#EXAM3
gradesf18[which(gradesf18$Exam.3..395005. == 0),]$Exam.3..395005. = NA
gradesf19[which(gradesf19$Open.Ended.Exam.3..875116. == 0),]$Open.Ended.Exam.3..875116. = NA
gradesf21[which(gradesf21$Exam..3..2184781. == 0),]$Exam..3..2184781. = NA
gradesf21$Exam..3..2184781. = gradesf21$Exam..3..2184781./25*100
gradesf22[which(gradesf22$Open.Ended.Exam..3..2592816. == 0),]$Open.Ended.Exam..3..2592816. = NA
gradesf22$Open.Ended.Exam..3..2592816. = gradesf22$Open.Ended.Exam..3..2592816./25*100
gradesf23[which(gradesf23$Open.Ended.Exam..3..3262289. == 0),]$Open.Ended.Exam..3..3262289. = NA
gradesf23$Open.Ended.Exam..3..3262289. = gradesf23$Open.Ended.Exam..3..3262289./25*100
allStats = as.data.frame.matrix( rbind(
summary(gradesf18$Final.exam..408510.),
summary(gradesf19$Open.Ended.Exam.3..875116.),
summary(gradesf21$Exam..3..2184781.),
summary(gradesf22$Open.Ended.Exam..3..2592816.),
summary(gradesf23$Open.Ended.Exam..3..3262289.)
))
row.names(allStats) = c("Fall18","Fall19","Fall21","Fall22","Fall23")
knitr::kable(allStats,caption = "Exam 3 Statistics",digits = 1)
Min. | 1st Qu. | Median | Mean | 3rd Qu. | Max. | NA’s | |
---|---|---|---|---|---|---|---|
Fall18 | 48.9 | 72.4 | 81.4 | 79.9 | 88.3 | 99 | 5 |
Fall19 | 2.5 | 42.5 | 55.0 | 56.4 | 72.5 | 95 | 5 |
Fall21 | 9.3 | 38.0 | 52.8 | 51.2 | 64.7 | 99 | 11 |
Fall22 | 21.0 | 50.0 | 63.0 | 62.1 | 76.3 | 98 | 5 |
Fall23 | 12.0 | 48.0 | 64.0 | 62.5 | 81.2 | 98 | 7 |
#FINAL EXAM
gradesf19[which(gradesf19$Final.exam.Unposted.Current.Score == 0),]$Final.exam.Unposted.Current.Score = NA
gradesf21[which(gradesf21$Final.Written.Exam.Current.Score == 0),]$Final.Written.Exam.Current.Score = NA
#gradesf22[which(gradesf22$Final.Written.Exam.Current.Score == 0),]$Final.Written.Exam.Current.Score = NA
allStats = as.data.frame.matrix( rbind(
summary(gradesf18$Final.exam..408510.),
summary(gradesf19$Final.exam.Unposted.Current.Score),
summary(gradesf21$Final.Written.Exam.Current.Score),
summary(gradesf22$Final.Written.Exam.Current.Score),
summary(gradesf23$Final.Written.Exam.Current.Score)
))
row.names(allStats) = c("Fall18","Fall19","Fall21","Fall22","Fall23")
knitr::kable(allStats,caption = "Final Exam Statistics",digits = 1)
Min. | 1st Qu. | Median | Mean | 3rd Qu. | Max. | NA’s | |
---|---|---|---|---|---|---|---|
Fall18 | 48.9 | 72.4 | 81.4 | 79.9 | 88.3 | 99.0 | 5 |
Fall19 | 33.7 | 55.3 | 64.8 | 65.3 | 75.7 | 97.3 | 5 |
Fall21 | 14.7 | 49.5 | 63.7 | 63.5 | 76.0 | 100.0 | 5 |
Fall22 | 40.3 | 60.4 | 67.2 | 68.7 | 77.9 | 93.9 | 1 |
Fall23 | 0.0 | 57.6 | 66.9 | 65.2 | 75.8 | 93.6 | 0 |
#filter for at1
m1f19_att1 = m1f19[which(m1f19$attempt == "1"),]
m1f21_att1 = m1f21[which(m1f21$attempt == "1"),]
m1f22_att1 = m1f22[which(m1f22$attempt == "1"),]
m1f23_att1 = m1f23[which(m1f23$attempt == "1"),]
makeTable = function(m1f19_att1, m1f21_att1, m1f22_att1, m1f23_att1 ){
n19 = length(m1f19_att1$score)
nA19 = length(m1f19_att1[which(m1f19_att1$score > 79.99),]$score)
nC19 = length(m1f19_att1[which(m1f19_att1$score > 69.99 & m1f19_att1$score < 79.99),]$score)
nF19 = length(m1f19_att1[which(m1f19_att1$score < 70.00),]$score)
n21 = length(m1f21_att1$score)
nA21 = length(m1f21_att1[which(m1f21_att1$score > 79.99),]$score)
nC21 = length(m1f21_att1[which(m1f21_att1$score > 69.99 & m1f21_att1$score < 79.99),]$score)
nF21 = length(m1f21_att1[which(m1f21_att1$score < 70.00),]$score)
n22 = length(m1f22_att1$score)
nA22 = length(m1f22_att1[which(m1f22_att1$score > 79.99),]$score)
nC22 = length(m1f22_att1[which(m1f22_att1$score > 69.99 & m1f22_att1$score < 79.99),]$score)
nF22 = length(m1f22_att1[which(m1f22_att1$score < 70.00),]$score)
n23 = length(m1f23_att1$score)
nA23 = length(m1f23_att1[which(m1f23_att1$score > 79.99),]$score)
nC23 = length(m1f23_att1[which(m1f23_att1$score > 69.99 & m1f23_att1$score < 79.99),]$score)
nF23 = length(m1f23_att1[which(m1f23_att1$score < 70.00),]$score)
combined_summary = bind_rows(describe(m1f19_att1$score),describe(m1f21_att1$score),describe(m1f22_att1$score),describe(m1f23_att1$score))
combined_summary <- subset(combined_summary, select = c("n", "mean", "sd", "median", "min","max"))
colnames(combined_summary)[colnames(combined_summary) == "n"] <- "students"
rownames(combined_summary) = c("F19","F21","F22","F23")
colnames(combined_summary)[0] <- "Semester"
combined_summary$`# / % A scores` = c(
paste0( nA19, " / ", round(nA19/n19*100, digits = 1),"%"),
paste0( nA21, " / ", round(nA21/n21*100, digits = 1),"%"),
paste0( nA22, " / ", round(nA22/n22*100, digits = 1),"%"),
paste0( nA23, " / ", round(nA23/n23*100, digits = 1),"%")
)
combined_summary$`# / % C scores` = c(
paste0( nC19, " / ", round(nC19/n19*100, digits = 1),"%"),
paste0( nC21, " / ", round(nC21/n21*100, digits = 1),"%"),
paste0( nC22, " / ", round(nC22/n22*100, digits = 1),"%"),
paste0( nC23, " / ", round(nC23/n23*100, digits = 1),"%")
)
combined_summary$`# / % F scores` = c(
paste0( nF19, " / ", round(nF19/n19*100, digits = 1),"%"),
paste0( nF21, " / ", round(nF21/n21*100, digits = 1),"%"),
paste0( nF22, " / ", round(nF22/n22*100, digits = 1),"%"),
paste0( nF23, " / ", round(nF23/n23*100, digits = 1),"%")
)
table <- kable(combined_summary, format = "markdown")
return(table)
}
# Apply some additional formatting if needed
#table <- table %>%
# kable_styling(full_width = FALSE) %>%
# add_header_above(c("Statistic" = 1, "Value" = 1)) %>%
# row_spec(0, bold = TRUE)
table = makeTable(m1f19_att1, m1f21_att1, m1f22_att1, m1f23_att1 )
table
students | mean | sd | median | min | max | # / % A scores | # / % C scores | # / % F scores | |
---|---|---|---|---|---|---|---|---|---|
F19 | 191 | 86.59701 | 11.47493 | 89.28000 | 35.92683 | 100 | 150 / 78.5% | 23 / 12% | 18 / 9.4% |
F21 | 211 | 84.70227 | 13.83789 | 87.80250 | 11.11667 | 100 | 152 / 72% | 33 / 15.6% | 26 / 12.3% |
F22 | 220 | 82.94547 | 13.94072 | 85.58783 | 40.71200 | 100 | 144 / 65.5% | 35 / 15.9% | 41 / 18.6% |
F23 | 163 | 82.12047 | 16.51057 | 87.83817 | 23.49350 | 100 | 107 / 65.6% | 22 / 13.5% | 34 / 20.9% |
m1f19_att1 = m1f19[which(m1f19$attempt == "1" | m1f19$attempt == "2" ),]
m1f21_att1 = m1f21[which(m1f21$attempt == "1" | m1f21$attempt == "2" ),]
m1f22_att1 = m1f22[which(m1f22$attempt == "1" | m1f22$attempt == "2" ),]
m1f23_att1 = m1f23[which(m1f23$attempt == "1" | m1f23$attempt == "2" ),]
chooseHighest = function(df){
df <- df %>%
group_by(id) %>%
filter(score == max(score))
return(df)
}
m1f19_att1 = chooseHighest(m1f19_att1)
m1f21_att1 = chooseHighest(m1f21_att1)
m1f22_att1 = chooseHighest(m1f22_att1)
m1f23_att1 = chooseHighest(m1f23_att1)
table = makeTable(m1f19_att1,
m1f21_att1,
m1f22_att1,
m1f23_att1 )
table
students | mean | sd | median | min | max | # / % A scores | # / % C scores | # / % F scores | |
---|---|---|---|---|---|---|---|---|---|
F19 | 191 | 88.45648 | 8.922470 | 90.00200 | 58.64667 | 100 | 168 / 88% | 15 / 7.9% | 8 / 4.2% |
F21 | 211 | 87.57826 | 11.124503 | 89.43867 | 27.53433 | 100 | 177 / 83.9% | 23 / 10.9% | 11 / 5.2% |
F22 | 220 | 86.62394 | 9.930089 | 88.33600 | 54.61150 | 100 | 173 / 78.6% | 33 / 15% | 14 / 6.4% |
F23 | 163 | 86.75313 | 10.975111 | 89.29000 | 23.49350 | 100 | 128 / 78.5% | 24 / 14.7% | 11 / 6.7% |
m1f19_att1 = m1f19[which(m1f19$attempt == "1" | m1f19$attempt == "2" | m1f19$attempt == "3" ),]
m1f21_att1 = m1f21[which(m1f21$attempt == "1" | m1f21$attempt == "2" | m1f21$attempt == "3" ),]
m1f22_att1 = m1f22[which(m1f22$attempt == "1" | m1f22$attempt == "2" | m1f22$attempt == "3" ),]
m1f23_att1 = m1f23[which(m1f23$attempt == "1" | m1f23$attempt == "2" | m1f23$attempt == "3" ),]
m1f19_att1 = chooseHighest(m1f19_att1)
m1f21_att1 = chooseHighest(m1f21_att1)
m1f22_att1 = chooseHighest(m1f22_att1)
m1f23_att1 = chooseHighest(m1f23_att1)
table = makeTable(m1f19_att1,
m1f21_att1,
m1f22_att1,
m1f23_att1 )
table
students | mean | sd | median | min | max | # / % A scores | # / % C scores | # / % F scores | |
---|---|---|---|---|---|---|---|---|---|
F19 | 191 | 89.05406 | 8.190662 | 90.28167 | 58.64667 | 100 | 175 / 91.6% | 11 / 5.8% | 5 / 2.6% |
F21 | 211 | 88.15861 | 10.280442 | 89.43867 | 27.53433 | 100 | 180 / 85.3% | 26 / 12.3% | 5 / 2.4% |
F22 | 220 | 88.12103 | 8.473910 | 88.89125 | 55.81883 | 100 | 194 / 88.2% | 19 / 8.6% | 7 / 3.2% |
F23 | 163 | 88.18607 | 10.009504 | 89.60533 | 23.49350 | 100 | 142 / 87.1% | 13 / 8% | 8 / 4.9% |
m2f19_att1 = m2f19[which(m2f19$attempt == "1" ),]
m2f21_att1 = m2f21[which(m2f21$attempt == "1" ),]
m2f22_att1 = m2f22[which(m2f22$attempt == "1" ),]
m2f23_att1 = m2f23[which(m2f23$attempt == "1" ),]
m2f19_att1 = chooseHighest(m2f19_att1)
m2f21_att1 = chooseHighest(m2f21_att1)
m2f22_att1 = chooseHighest(m2f22_att1)
m2f23_att1 = chooseHighest(m2f23_att1)
table = makeTable(m2f19_att1,
m2f21_att1,
m2f22_att1,
m2f23_att1 )
table
students | mean | sd | median | min | max | # / % A scores | # / % C scores | # / % F scores | |
---|---|---|---|---|---|---|---|---|---|
F19 | 190 | 87.24709 | 10.81401 | 90.35901 | 39.07243 | 100 | 152 / 80% | 22 / 11.6% | 16 / 8.4% |
F21 | 205 | 77.56799 | 14.75559 | 79.77267 | 37.10763 | 100 | 102 / 49.8% | 51 / 24.9% | 52 / 25.4% |
F22 | 216 | 81.86074 | 12.90459 | 85.01722 | 38.42122 | 100 | 136 / 63% | 40 / 18.5% | 40 / 18.5% |
F23 | 158 | 82.34789 | 14.76793 | 85.93283 | 29.16567 | 100 | 110 / 69.6% | 17 / 10.8% | 31 / 19.6% |
m2f19_att1 = m2f19[which(m2f19$attempt == "1" | m2f19$attempt == "2" ),]
m2f21_att1 = m2f21[which(m2f21$attempt == "1" | m2f21$attempt == "2" ),]
m2f22_att1 = m2f22[which(m2f22$attempt == "1" | m2f22$attempt == "2" ),]
m2f23_att1 = m2f23[which(m2f23$attempt == "1" | m2f23$attempt == "2" ),]
m2f19_att1 = chooseHighest(m2f19_att1)
m2f21_att1 = chooseHighest(m2f21_att1)
m2f22_att1 = chooseHighest(m2f22_att1)
m2f23_att1 = chooseHighest(m2f23_att1)
table = makeTable(m2f19_att1,
m2f21_att1,
m2f22_att1,
m2f23_att1 )
table
students | mean | sd | median | min | max | # / % A scores | # / % C scores | # / % F scores | |
---|---|---|---|---|---|---|---|---|---|
F19 | 190 | 88.71861 | 9.371188 | 90.43986 | 39.07243 | 100 | 171 / 90% | 10 / 5.3% | 9 / 4.7% |
F21 | 205 | 81.02490 | 12.313678 | 83.10267 | 37.10763 | 100 | 128 / 62.4% | 43 / 21% | 34 / 16.6% |
F22 | 216 | 85.05377 | 10.152792 | 86.92933 | 46.45111 | 100 | 165 / 76.4% | 31 / 14.4% | 20 / 9.3% |
F23 | 158 | 85.05217 | 11.825039 | 87.05144 | 30.41511 | 100 | 121 / 76.6% | 20 / 12.7% | 17 / 10.8% |
m2f19_att1 = m2f19[which(m2f19$attempt == "1" | m2f19$attempt == "2" | m2f19$attempt == "3" ),]
m2f21_att1 = m2f21[which(m2f21$attempt == "1" | m2f21$attempt == "2" | m2f21$attempt == "3" ),]
m2f22_att1 = m2f22[which(m2f22$attempt == "1" | m2f22$attempt == "2" | m2f22$attempt == "3" ),]
m2f23_att1 = m2f23[which(m2f23$attempt == "1" | m2f23$attempt == "2" | m2f23$attempt == "3" ),]
m2f19_att1 = chooseHighest(m2f19_att1)
m2f21_att1 = chooseHighest(m2f21_att1)
m2f22_att1 = chooseHighest(m2f22_att1)
m2f23_att1 = chooseHighest(m2f23_att1)
table = makeTable(m2f19_att1,
m2f21_att1,
m2f22_att1,
m2f23_att1 )
table
students | mean | sd | median | min | max | # / % A scores | # / % C scores | # / % F scores | |
---|---|---|---|---|---|---|---|---|---|
F19 | 190 | 89.20468 | 8.464771 | 90.43986 | 39.07243 | 100 | 175 / 92.1% | 10 / 5.3% | 5 / 2.6% |
F21 | 205 | 82.64865 | 10.762921 | 84.18644 | 37.10763 | 100 | 140 / 68.3% | 41 / 20% | 24 / 11.7% |
F22 | 216 | 86.50969 | 8.566437 | 87.95989 | 53.28894 | 100 | 183 / 84.7% | 21 / 9.7% | 12 / 5.6% |
F23 | 158 | 86.04928 | 10.614212 | 87.43781 | 30.41511 | 100 | 128 / 81% | 19 / 12% | 11 / 7% |
m3f19_att1 = m3f19[which(m3f19$attempt == "1" ),]
m3f21_att1 = m3f21[which(m3f21$attempt == "1" ),]
m3f22_att1 = m3f22[which(m3f22$attempt == "1" ),]
m3f23_att1 = m3f23[which(m3f23$attempt == "1" ),]
m3f19_att1 = chooseHighest(m3f19_att1)
m3f21_att1 = chooseHighest(m3f21_att1)
m3f22_att1 = chooseHighest(m3f22_att1)
m3f23_att1 = chooseHighest(m3f23_att1)
table = makeTable(m3f19_att1,
m3f21_att1,
m3f22_att1,
m3f23_att1 )
table
students | mean | sd | median | min | max | # / % A scores | # / % C scores | # / % F scores | |
---|---|---|---|---|---|---|---|---|---|
F19 | 183 | 87.08412 | 9.75140 | 88.51711 | 49.98278 | 100 | 151 / 82.5% | 21 / 11.5% | 11 / 6% |
F21 | 195 | 81.63402 | 15.31543 | 85.99000 | 24.37333 | 100 | 122 / 62.6% | 30 / 15.4% | 43 / 22.1% |
F22 | 210 | 79.51752 | 16.25780 | 84.11167 | 9.18000 | 100 | 128 / 61% | 33 / 15.7% | 49 / 23.3% |
F23 | 151 | 82.07987 | 13.73418 | 86.29667 | 43.91667 | 100 | 104 / 68.9% | 17 / 11.3% | 30 / 19.9% |
m3f19_att1 = m3f19[which(m3f19$attempt == "1" | m3f19$attempt == "2" ),]
m3f21_att1 = m3f21[which(m3f21$attempt == "1" | m3f21$attempt == "2" ),]
m3f22_att1 = m3f22[which(m3f22$attempt == "1" | m3f22$attempt == "2" ),]
m3f23_att1 = m3f23[which(m3f23$attempt == "1" | m3f23$attempt == "2" ),]
m3f19_att1 = chooseHighest(m3f19_att1)
m3f21_att1 = chooseHighest(m3f21_att1)
m3f22_att1 = chooseHighest(m3f22_att1)
m3f23_att1 = chooseHighest(m3f23_att1)
table = makeTable(m3f19_att1,
m3f21_att1,
m3f22_att1,
m3f23_att1 )
table
students | mean | sd | median | min | max | # / % A scores | # / % C scores | # / % F scores | |
---|---|---|---|---|---|---|---|---|---|
F19 | 183 | 88.55890 | 7.485728 | 88.65200 | 53.23144 | 100 | 166 / 90.7% | 14 / 7.7% | 3 / 1.6% |
F21 | 195 | 84.64072 | 11.961618 | 87.65000 | 45.64333 | 100 | 141 / 72.3% | 28 / 14.4% | 26 / 13.3% |
F22 | 210 | 83.22498 | 12.068709 | 85.37167 | 37.95333 | 100 | 147 / 70% | 34 / 16.2% | 29 / 13.8% |
F23 | 151 | 85.22079 | 10.182821 | 86.61667 | 44.83333 | 100 | 122 / 80.8% | 18 / 11.9% | 11 / 7.3% |
m3f19_att1 = m3f19[which(m3f19$attempt == "1" | m3f19$attempt == "2" | m3f19$attempt == "3" ),]
m3f21_att1 = m3f21[which(m3f21$attempt == "1" | m3f21$attempt == "2" | m3f21$attempt == "3" ),]
m3f22_att1 = m3f22[which(m3f22$attempt == "1" | m3f22$attempt == "2" | m3f22$attempt == "3" ),]
m3f23_att1 = m3f23[which(m3f23$attempt == "1" | m3f23$attempt == "2" | m3f23$attempt == "3" ),]
m3f19_att1 = chooseHighest(m3f19_att1)
m3f21_att1 = chooseHighest(m3f21_att1)
m3f22_att1 = chooseHighest(m3f22_att1)
m3f23_att1 = chooseHighest(m3f23_att1)
table = makeTable(m3f19_att1,
m3f21_att1,
m3f22_att1,
m3f23_att1 )
table
students | mean | sd | median | min | max | # / % A scores | # / % C scores | # / % F scores | |
---|---|---|---|---|---|---|---|---|---|
F19 | 183 | 88.84171 | 7.287616 | 88.88267 | 53.23144 | 100 | 171 / 93.4% | 9 / 4.9% | 3 / 1.6% |
F21 | 195 | 86.26802 | 10.446492 | 87.77333 | 45.64333 | 100 | 156 / 80% | 27 / 13.8% | 12 / 6.2% |
F22 | 210 | 84.88897 | 10.332357 | 86.15333 | 37.95333 | 100 | 162 / 77.1% | 33 / 15.7% | 15 / 7.1% |
F23 | 151 | 85.81885 | 9.479026 | 87.04190 | 44.83333 | 100 | 127 / 84.1% | 16 / 10.6% | 8 / 5.3% |
m4f19_att1 = m4f19[which(m4f19$attempt == "1" ),]
m4f21_att1 = m4f21[which(m4f21$attempt == "1" ),]
m4f22_att1 = m4f22[which(m4f22$attempt == "1" ),]
m4f23_att1 = m4f23[which(m4f23$attempt == "1" ),]
m4f19_att1 = chooseHighest(m4f19_att1)
m4f21_att1 = chooseHighest(m4f21_att1)
m4f22_att1 = chooseHighest(m4f22_att1)
m4f23_att1 = chooseHighest(m4f23_att1)
table = makeTable(m4f19_att1,
m4f21_att1,
m4f22_att1,
m4f23_att1 )
table
students | mean | sd | median | min | max | # / % A scores | # / % C scores | # / % F scores | |
---|---|---|---|---|---|---|---|---|---|
F19 | 177 | 79.27583 | 14.73094 | 81.64083 | 38.43000 | 100 | 96 / 54.2% | 37 / 20.9% | 44 / 24.9% |
F21 | 187 | 82.10934 | 13.27249 | 83.88033 | 47.22000 | 100 | 116 / 62% | 39 / 20.9% | 33 / 17.6% |
F22 | 206 | 79.04682 | 14.39811 | 81.80700 | 26.94200 | 100 | 114 / 55.3% | 41 / 19.9% | 53 / 25.7% |
F23 | 148 | 80.92414 | 14.35564 | 84.57617 | 44.43833 | 100 | 91 / 61.5% | 28 / 18.9% | 29 / 19.6% |
m4f19_att1 = m4f19[which(m4f19$attempt == "1" | m4f19$attempt == "2" ),]
m4f21_att1 = m4f21[which(m4f21$attempt == "1" | m4f21$attempt == "2" ),]
m4f22_att1 = m4f22[which(m4f22$attempt == "1" | m4f22$attempt == "2" ),]
m4f23_att1 = m4f23[which(m4f23$attempt == "1" | m4f23$attempt == "2" ),]
m4f19_att1 = chooseHighest(m4f19_att1)
m4f21_att1 = chooseHighest(m4f21_att1)
m4f22_att1 = chooseHighest(m4f22_att1)
m4f23_att1 = chooseHighest(m4f23_att1)
table = makeTable(m4f19_att1,
m4f21_att1,
m4f22_att1,
m4f23_att1 )
table
students | mean | sd | median | min | max | # / % A scores | # / % C scores | # / % F scores | |
---|---|---|---|---|---|---|---|---|---|
F19 | 177 | 83.85381 | 11.883539 | 86.58267 | 45.94233 | 100 | 125 / 70.6% | 30 / 16.9% | 22 / 12.4% |
F21 | 187 | 84.93125 | 11.022564 | 86.11333 | 51.10067 | 100 | 139 / 74.3% | 29 / 15.5% | 19 / 10.2% |
F22 | 206 | 83.85520 | 10.368770 | 84.99433 | 46.66800 | 100 | 146 / 70.9% | 43 / 20.9% | 18 / 8.7% |
F23 | 148 | 85.15438 | 9.762059 | 86.24550 | 46.65800 | 100 | 112 / 75.7% | 24 / 16.2% | 12 / 8.1% |
m4f19_att1 = m4f19[which(m4f19$attempt == "1" | m4f19$attempt == "2" | m4f19$attempt == "3" ),]
m4f21_att1 = m4f21[which(m4f21$attempt == "1" | m4f21$attempt == "2" | m4f21$attempt == "3" ),]
m4f22_att1 = m4f22[which(m4f22$attempt == "1" | m4f22$attempt == "2" | m4f22$attempt == "3" ),]
m4f23_att1 = m4f23[which(m4f23$attempt == "1" | m4f23$attempt == "2" | m4f23$attempt == "3" ),]
m4f19_att1 = chooseHighest(m4f19_att1)
m4f21_att1 = chooseHighest(m4f21_att1)
m4f22_att1 = chooseHighest(m4f22_att1)
m4f23_att1 = chooseHighest(m4f23_att1)
table = makeTable(m4f19_att1,
m4f21_att1,
m4f22_att1,
m4f23_att1 )
table
students | mean | sd | median | min | max | # / % A scores | # / % C scores | # / % F scores | |
---|---|---|---|---|---|---|---|---|---|
F19 | 177 | 85.56451 | 10.407627 | 87.21733 | 45.94233 | 100 | 141 / 79.7% | 22 / 12.4% | 14 / 7.9% |
F21 | 187 | 86.17210 | 9.920564 | 86.94967 | 51.10067 | 100 | 149 / 79.7% | 26 / 13.9% | 12 / 6.4% |
F22 | 206 | 84.98724 | 9.406832 | 86.10917 | 46.66800 | 100 | 159 / 77.2% | 37 / 18% | 11 / 5.3% |
F23 | 148 | 85.99251 | 8.627701 | 86.24800 | 46.65800 | 100 | 118 / 79.7% | 24 / 16.2% | 6 / 4.1% |
Milestone 1
#count
countGiveUp = function(df){
# Create a table of name counts
name_counts <- table(df$id)
# Create a logical vector indicating names that appear three times or more
to_remove <- df$id %in% names(name_counts[name_counts >= 3])
# Create a logical vector indicating names with at least one score > 80
to_remove_scores <- df$id %in% unique(df$id[df$score > 80.00])
# Combine the two logical vectors using OR to get the final rows to remove
final_to_remove <- to_remove | to_remove_scores
# Filter the dataframe to keep only the valid rows
df <- df[!final_to_remove, ]
df = subset(df, select = c("name", "id", "attempt", "score"))
return(df)
}
giveUp19 = countGiveUp(m1f19)
giveUp21 = countGiveUp(m1f21)
giveUp22 = countGiveUp(m1f22)
giveUp23 = countGiveUp(m1f23)
name_counts <- table(giveUp19$id)
twice19 <- length(names(name_counts[name_counts == 2]))
once19 <- length(names(name_counts[name_counts == 1]))
name_counts <- table(giveUp21$id)
twice21 <- length(names(name_counts[name_counts == 2]))
once21 <- length(names(name_counts[name_counts == 1]))
name_counts <- table(giveUp22$id)
twice22 <- length(names(name_counts[name_counts == 2]))
once22 <- length(names(name_counts[name_counts == 1]))
name_counts <- table(giveUp23$id)
twice23 <- length(names(name_counts[name_counts == 2]))
once23 <- length(names(name_counts[name_counts == 1]))
writeAttemptTable <- function(numbers, titles, table_title) {
if(length(numbers) != length(titles)) {
stop("Length of numbers and titles must be the same.")
}
df <- data.frame(matrix(nrow = 1, ncol = length(numbers)))
colnames(df) <- titles
df[1,] <- numbers
#attr(df, "title") <- table_title
return(df)
}
#M1
numbers <- c(
length(unique(giveUp19$id)),
length(unique(giveUp21$id)),
length(unique(giveUp22$id)),
length(unique(giveUp23$id))
)
titles <- c("F19", "F21", "F22", "F23")
table <- writeAttemptTable(numbers, titles,"Students who settled for a lower score without trying 3 attempts. Milestone 1")
#M2
giveUp19 = countGiveUp(m2f19)
giveUp21 = countGiveUp(m2f21)
giveUp22 = countGiveUp(m2f22)
giveUp23 = countGiveUp(m2f23)
numbers <- c(
length(unique(giveUp19$id)),
length(unique(giveUp21$id)),
length(unique(giveUp22$id)),
length(unique(giveUp23$id))
)
titles <- c("F19", "F21", "F22", "F23")
table2 <- writeAttemptTable(numbers, titles,"Students who settled for a lower score without trying 3 attempts. Milestone 2")
table = rbind(table, table2)
#M3
giveUp19 = countGiveUp(m3f19)
giveUp21 = countGiveUp(m3f21)
giveUp22 = countGiveUp(m3f22)
giveUp23 = countGiveUp(m3f23)
numbers <- c(
length(unique(giveUp19$id)),
length(unique(giveUp21$id)),
length(unique(giveUp22$id)),
length(unique(giveUp23$id))
)
titles <- c("F19", "F21", "F22", "F23")
table2 <- writeAttemptTable(numbers, titles,"Students who settled for a lower score without trying 3 attempts. Milestone 3")
table = rbind(table, table2)
#M4
giveUp19 = countGiveUp(m4f19)
giveUp21 = countGiveUp(m4f21)
giveUp22 = countGiveUp(m4f22)
giveUp23 = countGiveUp(m4f23)
numbers <- c(
length(unique(giveUp19$id)),
length(unique(giveUp21$id)),
length(unique(giveUp22$id)),
length(unique(giveUp23$id))
)
titles <- c("F19", "F21", "F22", "F23")
table2 <- writeAttemptTable(numbers, titles,"Students who settled for a lower score without trying 3 attempts. Milestone 4")
table = rbind(table, table2)
rownames(table) = c(
"Milestone 1",
"Milestone 2",
"Milestone 3",
"Milestone 4"
)
knitr::kable(table, caption="Students who settled for a lower score without trying 3 attempts.")
F19 | F21 | F22 | F23 | |
---|---|---|---|---|
Milestone 1 | 14 | 23 | 13 | 12 |
Milestone 2 | 9 | 32 | 16 | 14 |
Milestone 3 | 7 | 23 | 19 | 14 |
Milestone 4 | 14 | 25 | 31 | 18 |
f18m1 = suppressWarnings(as.numeric( gradesf18mood$Quiz.Milestone.1..Do.not.take.it.outside.of.class..Requires.Respondus.LockDown.Browser..Real.))
f18m2 = suppressWarnings(as.numeric( gradesf18mood$Quiz.Milestone.2...Do.not.take.it.outside.of.class...Requires.Respondus.LockDown.Browser..Real.))
f18m3 = suppressWarnings(as.numeric( gradesf18mood$Quiz.Milestone.3...Do.not.take.it.outside.of.class..Requires.Respondus.LockDown.Browser..Real.))
f18m4 = suppressWarnings(as.numeric( gradesf18mood$Quiz.Milestone.4...Do.not.take.it.outside.of.class..Requires.Respondus.LockDown.Browser..Real.))
allStats = as.data.frame.matrix( rbind(
summary(f18m1),
summary(gradesf19$Milestone.1.Quiz..Requires.Respondus.LockDown.Browser..798227.),
summary(gradesf21$Milestone.1..Requires.Respondus.LockDown.Browser..1911986.),
summary(gradesf22$Milestone.1..Requires.Respondus.LockDown.Browser..2592695.),
summary(gradesf23$Milestone.1..Requires.Respondus.LockDown.Browser..3262166.)
))
allStats$`NA's` = NULL
row.names(allStats) = c("Fall18","Fall19","Fall21","Fall22","Fall23")
knitr::kable(allStats,caption = "Milestone 1 raw score",digits = 1)
Min. | 1st Qu. | Median | Mean | 3rd Qu. | Max. | |
---|---|---|---|---|---|---|
Fall18 | 51.2 | 88.2 | 94.0 | 92.3 | 98.4 | 100 |
Fall19 | 71.9 | 84.5 | 90.5 | 89.9 | 95.9 | 100 |
Fall21 | 51.2 | 84.4 | 89.8 | 89.4 | 96.0 | 100 |
Fall22 | 61.2 | 84.0 | 89.2 | 89.1 | 94.5 | 100 |
Fall23 | 23.5 | 85.1 | 90.0 | 89.2 | 95.6 | 100 |
allStats = as.data.frame.matrix( rbind(
summary(f18m2),
summary(gradesf19$Milestone.2.Quiz..Requires.Respondus.LockDown.Browser..823364.),
summary(gradesf21$Milestone.2..Requires.Respondus.LockDown.Browser..1912009.),
summary(gradesf22$Milestone.2..Requires.Respondus.LockDown.Browser..2592715.),
summary(gradesf23$Milestone.2..Requires.Respondus.LockDown.Browser..3262143.)
))
row.names(allStats) = c("Fall18","Fall19","Fall21","Fall22","Fall23")
allStats$`NA's` = NULL
knitr::kable(allStats,caption = "Milestone 2 raw score",digits = 1)
Min. | 1st Qu. | Median | Mean | 3rd Qu. | Max. | |
---|---|---|---|---|---|---|
Fall18 | 55.6 | 84.4 | 91.6 | 90.0 | 96.0 | 100 |
Fall19 | 67.0 | 85.6 | 90.6 | 90.1 | 95.7 | 100 |
Fall21 | 37.1 | 79.3 | 84.9 | 84.1 | 90.1 | 100 |
Fall22 | 53.3 | 82.8 | 88.0 | 87.2 | 92.4 | 100 |
Fall23 | 30.4 | 81.7 | 88.2 | 87.2 | 94.2 | 100 |
allStats = as.data.frame.matrix( rbind(
summary(f18m3),
summary(gradesf19$Milestone.3.Quiz..Requires.Respondus.LockDown.Browser..841979.),
summary(gradesf21$Milestone.3..Requires.Respondus.LockDown.Browser..2192128.),
summary(gradesf22$Milestone.3..Requires.Respondus.LockDown.Browser..2592728.),
summary(gradesf23$Milestone.3..Requires.Respondus.LockDown.Browser..3262146.)
))
row.names(allStats) = c("Fall18","Fall19","Fall21","Fall22","Fall23")
knitr::kable(allStats,caption = "Milestone 3 raw score",digits = 1)
Min. | 1st Qu. | Median | Mean | 3rd Qu. | Max. | NA’s | |
---|---|---|---|---|---|---|---|
Fall18 | 35.4 | 86.8 | 92.4 | 90.5 | 96.7 | 100 | 3 |
Fall19 | 64.4 | 84.2 | 89.5 | 89.2 | 94.4 | 100 | 2 |
Fall21 | 48.4 | 82.3 | 88.0 | 87.4 | 94.1 | 100 | 4 |
Fall22 | 38.2 | 81.4 | 86.3 | 85.8 | 91.8 | 100 | 1 |
Fall23 | 44.8 | 82.2 | 87.2 | 86.4 | 92.1 | 100 | 3 |
allStats = as.data.frame.matrix( rbind(
summary(f18m4),
summary(gradesf19$Milestone.4.Quiz..Requires.Respondus.LockDown.Browser..860755.),
summary(gradesf21$Milestone.4..Requires.Respondus.LockDown.Browser..2216543.),
summary(gradesf22$Milestone.4..Requires.Respondus.LockDown.Browser..2592732.),
summary(gradesf23$Milestone.4..Requires.Respondus.LockDown.Browser..3262167.)
))
row.names(allStats) = c("Fall18","Fall19","Fall21","Fall22","Fall23")
knitr::kable(allStats,caption = "Milestone 4 raw score",digits = 1)
Min. | 1st Qu. | Median | Mean | 3rd Qu. | Max. | NA’s | |
---|---|---|---|---|---|---|---|
Fall18 | 44.0 | 82.6 | 88.9 | 87.2 | 94.6 | 100 | 5 |
Fall19 | 46.4 | 83.4 | 87.5 | 86.4 | 92.2 | 100 | 5 |
Fall21 | 51.1 | 81.7 | 87.0 | 86.4 | 94.4 | 100 | 8 |
Fall22 | 46.7 | 80.6 | 86.4 | 85.3 | 91.4 | 100 | 3 |
Fall23 | 46.7 | 81.6 | 86.2 | 86.0 | 91.7 | 100 | 3 |
library(ggplot2)
buildHeaders <- function(numberOfQuestions){
colHeaders = c()
#build headers
for (n in seq(numberOfQuestions)){
colHeaders = c(colHeaders,paste("q",as.character(n),sep = ""))
}
return(colHeaders)
}
buildDF_fromMilestone <- function(m1,numberOfQuestions){
#Build df with just answers
totcol = ncol(m1)
m1df = data.frame( matrix(ncol=numberOfQuestions+3,nrow=0) )
colHeaders = c(buildHeaders(numberOfQuestions),"total")
studNames = c()
attNumb = c()
#loop over students or row
for (st in seq(1,nrow(m1)) ){
#build attemptNumb and studNames. theyll be added as columns later
attNumb = c(attNumb,m1[st,8])
studNames = c(studNames,m1[st,1])
#empty the score array and build it up as it finds each question
thisSt = rep(NA,numberOfQuestions)
#loop over columns to find nonempty scores
for (q in seq(10,totcol-2,2)){
score = m1[st,q]
if ( !is.na( score ) ){
questionNumber = colnames(m1)[q-1]
questionNumber = unlist(strsplit(questionNumber,"_"))[1]
questionNumber = as.numeric( gsub("^q","",questionNumber))
thisSt[questionNumber] = score
}
}
#studNames = c(studNames,m1[st,1])
thisSt = c(thisSt, m1[st,totcol])
m1df = rbind(m1df,thisSt)
}
colnames(m1df) = colHeaders
m1df = rbind(m1df,colMeans(m1df))
m1df$studName = c(studNames,NA)
m1df$attNumb = c(attNumb,NA)
return(m1df)
}
roundThisScore <- function(score){
if (score <70){ r = 0
} else if (score <80){ r = 80
} else if (score >80){ r = 100 }
return(r)
}
flowAndSettling <- function(m1df){
#check students who did not attempt a 3rd and got lower than 80
studs = unique(m1df$studName)
studs = studs[!is.na(studs)]
settle = data.frame( matrix(ncol=3,nrow=0) )
flow = data.frame(matrix(ncol=3,nrow=0))
for (stud in studs){
thisStDF = m1df[which(m1df$studName == stud),]
#if att number lower than 3 and score lower than 80
maxNum = max(thisStDF$attNumb)
maxScore = max(thisStDF$total)
if ( maxNum < 3 & maxScore < 80 ){
settle = rbind(settle,c(stud,maxNum,maxScore))
}
sc1 = roundThisScore( max(m1df[which(m1df$studName == stud & m1df$attNumb < 2),]$total) )
sc2 = roundThisScore( max(m1df[which(m1df$studName == stud & m1df$attNumb < 3),]$total) )
sc3 = roundThisScore( max(m1df[which(m1df$studName == stud & m1df$attNumb < 4),]$total) )
flow = rbind(flow,c(sc1,sc2,sc3))
}
colnames(flow) = c("one","two","three")
flow2 = data.frame(matrix(ncol=3,nrow=3))
flow2[,1]=table(flow$one)
flow2[,2]=table(flow$two)
flow2[,3]=table(flow$three)
colnames(flow2) = c("After 1st","After 2nd","After 3rd")
colnames(settle) = c("name","MaxAttempt","MaxScore")
all = list("settle" = settle,"flow" = flow2)
return(all)
}
compileStackAndGrouped = function(m1f21,numb_m1f21,m1f19,numb_m1f19){
m1df = buildDF_fromMilestone(m1f21,numb_m1f21)
results = flowAndSettling(m1df)
flow = results$flow
pct1st = flow[,1]/sum(flow[,1])*100
pct2nd = flow[,2]/sum(flow[,2])*100
pct3rd = flow[,3]/sum(flow[,3])*100
stackAndGrouped = data.frame(matrix(ncol = 4,nrow=0))
stackAndGrouped = rbind(stackAndGrouped,c("F",pct1st[1],"F21","First"))
stackAndGrouped = rbind(stackAndGrouped,c("C",pct1st[2],"F21","First"))
stackAndGrouped = rbind(stackAndGrouped,c("A",pct1st[3],"F21","First"))
stackAndGrouped = rbind(stackAndGrouped,c("F",pct2nd[1],"F21","Second"))
stackAndGrouped = rbind(stackAndGrouped,c("C",pct2nd[2],"F21","Second"))
stackAndGrouped = rbind(stackAndGrouped,c("A",pct2nd[3],"F21","Second"))
stackAndGrouped = rbind(stackAndGrouped,c("F",pct3rd[1],"F21","Third"))
stackAndGrouped = rbind(stackAndGrouped,c("C",pct3rd[2],"F21","Third"))
stackAndGrouped = rbind(stackAndGrouped,c("A",pct3rd[3],"F21","Third"))
m1df19 = buildDF_fromMilestone(m1f19,numb_m1f19)
results19 = flowAndSettling(m1df19)
flow19 = results19$flow
pct1st = flow19[,1]/sum(flow19[,1])*100
pct2nd = flow19[,2]/sum(flow19[,2])*100
pct3rd = flow19[,3]/sum(flow19[,3])*100
stackAndGrouped = rbind(stackAndGrouped,c("F",pct1st[1],"F19","First"))
stackAndGrouped = rbind(stackAndGrouped,c("C",pct1st[2],"F19","First"))
stackAndGrouped = rbind(stackAndGrouped,c("A",pct1st[3],"F19","First"))
stackAndGrouped = rbind(stackAndGrouped,c("F",pct2nd[1],"F19","Second"))
stackAndGrouped = rbind(stackAndGrouped,c("C",pct2nd[2],"F19","Second"))
stackAndGrouped = rbind(stackAndGrouped,c("A",pct2nd[3],"F19","Second"))
stackAndGrouped = rbind(stackAndGrouped,c("F",pct3rd[1],"F19","Third"))
stackAndGrouped = rbind(stackAndGrouped,c("C",pct3rd[2],"F19","Third"))
stackAndGrouped = rbind(stackAndGrouped,c("A",pct3rd[3],"F19","Third"))
colnames(stackAndGrouped) = c("Grade","Pct","Year","Attempt")
stackAndGrouped$Pct = as.numeric(stackAndGrouped$Pct)
return(stackAndGrouped)
}
stackAndGrouped = compileStackAndGrouped(m1f21,12,m1f19,12)
ggplot() + geom_bar(data=stackAndGrouped, aes(y = Pct, x = Year, fill = Grade), stat="identity",
position='stack') +
theme_bw() +
ggtitle("Milestone 1: F19 vs F21")+
scale_fill_manual(values = c("green","yellow","red" )) +
facet_grid( ~ Attempt)
stackAndGrouped = compileStackAndGrouped(m2f21,11,m2f19,12)
ggplot() + geom_bar(data=stackAndGrouped, aes(y = Pct, x = Year, fill = Grade), stat="identity",
position='stack') +
theme_bw() +
ggtitle("Milestone 2: F19 vs F21")+
scale_fill_manual(values = c("green","yellow","red" )) +
facet_grid( ~ Attempt)
stackAndGrouped = compileStackAndGrouped(m3f21,13,m3f19,12)
ggplot() + geom_bar(data=stackAndGrouped, aes(y = Pct, x = Year, fill = Grade), stat="identity",
position='stack') +
theme_bw() +
ggtitle("Milestone 3: F19 vs F21")+
scale_fill_manual(values = c("green","yellow","red" )) +
facet_grid( ~ Attempt)
stackAndGrouped = compileStackAndGrouped(m4f21,12,m4f19,12)
ggplot() + geom_bar(data=stackAndGrouped, aes(y = Pct, x = Year, fill = Grade), stat="identity",
position='stack') +
theme_bw() +
ggtitle("Milestone 4: F19 vs F21")+
scale_fill_manual(values = c("green","yellow","red" )) +
facet_grid( ~ Attempt)
f18preclass = gradesf18[,grepl("class",names(gradesf18)) & grepl("X",names(gradesf18)) & !grepl("Score",names(gradesf18))]
f19preclass = gradesf19[,grepl("class",names(gradesf19)) & grepl("X",names(gradesf19)) & !grepl("Score",names(gradesf19))]
f21preclass = gradesf21[,grepl("class",names(gradesf21)) & grepl("X",names(gradesf21)) & !grepl("Score",names(gradesf21))]
gradesf18$missPreclass = rowSums( f18preclass == 0, na.rm = TRUE)
gradesf19$missPreclass = rowSums( f19preclass == 0, na.rm = TRUE)
gradesf21$missPreclass = rowSums( f21preclass == 0, na.rm = TRUE)
l = length(colnames(f21preclass))
#f21preclass[,l] = NULL
#f21preclass[,l-1] = NULL
plot(0+colSums(f18preclass == 0, na.rm = TRUE),type="l",col="black",ylim=c(0,40),xlab = "class day",ylab = "students missing preclass")
lines(0+colSums(f19preclass == 0,na.rm = TRUE),type="l",col="red")
lines(0+colSums(f21preclass < 1,na.rm = TRUE),type="l",col="green")
legend(1, 40, legend=c( paste("F2018 n=",nf18),
paste("F2019 n=",nf19),
paste("F2021 n=",nf21)), col=c("black", "red","green"),lty=1:1, cex=0.8)
title("Number of students missing each Preclass")
par(mfrow=c(1,3),
oma = c(5,4,0,0) + 0.1,
mar = c(0,0,1,1) + 0.1)
hist(rowSums( f18preclass == 0,na.rm = TRUE),breaks=10,xlim = c(0,15),ylim=c(0,140),main="Fall18",xlab="Number of preclass missed",ylab="Number of students")
hist(rowSums( f19preclass == 0,na.rm = TRUE),breaks=10,xlim = c(0,15),ylim=c(0,140),main="Fall19",xlab="Number of preclass missed",ylab="Number of students")
hist(rowSums( f21preclass == 0,na.rm = TRUE),breaks=10,xlim = c(0,15),ylim=c(0,140),main="Fall21",xlab="Number of preclass missed",ylab="Number of students")
f18hw = gradesf18[,grepl("Thu",names(gradesf18))]
f19hw = gradesf19[,grepl("Homework",names(gradesf19)) & !grepl("Score",names(gradesf19)) & !grepl("Homework.13th.week",names(gradesf19))]
for (i in 1:ncol(f19hw)){ f19hw[,i] = as.numeric(f19hw[,i])/12*100 }
f21hw = gradesf21[,grepl("Thu",names(gradesf21))]
for (i in 1:ncol(f21hw)){ f21hw[,i] = as.numeric(f21hw[,i])/12*100 }
hwfail = data.frame(matrix(ncol = 0,nrow=3))
for (i in 1:ncol(f21hw)){
hwfail[ paste("hw",i)]=c(
sum( f18hw[,i] < 70,na.rm = TRUE),
sum( f19hw[,i] < 70,na.rm = TRUE),
sum( f21hw[,i] < 70,na.rm = TRUE)
)
}
row.names(hwfail) = c("Fall18","Fall19","Fall21")
knitr::kable(hwfail,caption = "Number of students with homework scores below 70",digits = 1)
hw 1 | hw 2 | hw 3 | hw 4 | hw 5 | hw 6 | hw 7 | hw 8 | hw 9 | |
---|---|---|---|---|---|---|---|---|---|
Fall18 | 2 | 5 | 1 | 9 | 9 | 3 | 2 | 3 | 11 |
Fall19 | 1 | 4 | 4 | 15 | 44 | 4 | 6 | 3 | 21 |
Fall21 | 3 | 18 | 11 | 29 | 26 | 15 | 15 | 29 | 30 |
hwfail = data.frame(matrix(ncol = 0,nrow=3))
for (i in 1:ncol(f21hw)){
hwfail[ paste("hw",i)]=c(
sum( f18hw[,i] < 50,na.rm = TRUE),
sum( f19hw[,i] < 50,na.rm = TRUE),
sum( f21hw[,i] < 50,na.rm = TRUE)
)
}
row.names(hwfail) = c("Fall18","Fall19","Fall21")
knitr::kable(hwfail,caption = "Number of students with homework scores below 50",digits = 1)
hw 1 | hw 2 | hw 3 | hw 4 | hw 5 | hw 6 | hw 7 | hw 8 | hw 9 | |
---|---|---|---|---|---|---|---|---|---|
Fall18 | 0 | 4 | 0 | 4 | 3 | 2 | 0 | 1 | 5 |
Fall19 | 0 | 4 | 2 | 4 | 11 | 2 | 3 | 1 | 8 |
Fall21 | 1 | 8 | 2 | 18 | 10 | 7 | 8 | 17 | 18 |
f18report = gradesf18[, grepl("Reporting",names(gradesf18)) &
!grepl("Score",names(gradesf18))
]
f19report = gradesf19[, grepl("Reporting",names(gradesf19)) &
!grepl("Score",names(gradesf19))
]
f21report = gradesf21[,grepl("Reporting",names(gradesf21))]
for (i in 1:ncol(f18report)){
f18report[,i] = as.numeric(f18report[,i])
thismax = max(f18report[,i],na.rm = TRUE)
f18report[,i] = f18report[,i]/thismax*100
}
for (i in 1:ncol(f19report)){
f19report[,i] = as.numeric(f19report[,i])
thismax = max(f19report[,i],na.rm = TRUE)
f19report[,i] = f19report[,i]/thismax*100
}
for (i in 1:ncol(f21report)){
f21report[,i] = as.numeric(f21report[,i])
thismax = max(f21report[,i],na.rm = TRUE)
f21report[,i] = f21report[,i]/thismax*100
}
f21report = f21report[,order(names(f21report))]
f21report = f21report[,c(1,4,5,6,7,8,9,10,11,2,3)]
reportfail = data.frame(matrix(ncol = 0,nrow=3))
for (i in 1:ncol(f21report)){
reportfail[ paste("Report",i)]=c(
sum( f18report[,i] < 50,na.rm = TRUE),
sum( f19report[,i] < 50,na.rm = TRUE),
sum( f21report[,i] < 50,na.rm = TRUE)
)
}
row.names(reportfail) = c("Fall18","Fall19","Fall21")
knitr::kable(reportfail,caption = "Number of students with report scores below 50",digits = 1)
Report 1 | Report 2 | Report 3 | Report 4 | Report 5 | Report 6 | Report 7 | Report 8 | Report 9 | Report 10 | Report 11 | |
---|---|---|---|---|---|---|---|---|---|---|---|
Fall18 | 2 | 1 | 5 | 2 | 2 | 4 | 3 | 3 | 3 | 4 | 6 |
Fall19 | 2 | 11 | 26 | 16 | 10 | 10 | 17 | 10 | 18 | 13 | 14 |
Fall21 | 7 | 51 | 30 | 48 | 17 | 24 | 36 | 30 | 48 | 43 | 27 |
Missing a prelab is big deal because you are not allowed to turn in your report and the moment you miss more than two labs you automatically fail the course.
f18prelab = gradesf18[,grepl("Prelab",names(gradesf18)) & !grepl("Score",names(gradesf18))]
f19prelab = gradesf19[,grepl("Prelab",names(gradesf19)) & !grepl("Score",names(gradesf19))]
f21prelab = gradesf21[,grepl("Prelab",names(gradesf21)) & !grepl("Score",names(gradesf21))]
gradesf18$missPrelab = rowSums( f18prelab == 0, na.rm = TRUE)
gradesf19$missPrelab = rowSums( f19prelab == 0, na.rm = TRUE)
gradesf21$missPrelab = rowSums( f21prelab == 0, na.rm = TRUE)
plot(0+colSums(f18prelab == 0, na.rm = TRUE),type="l",col="black",ylim=c(0,8),xlab = "Lab day",ylab = "students missing prelab")
lines(0+colSums(f19prelab == 0,na.rm = TRUE),type="l",col="red")
lines(0+colSums(f21prelab < 1,na.rm = TRUE),type="l",col="green")
legend("topright", legend=c( paste("F2018 n=",nf18),
paste("F2019 n=",nf19),
paste("F2021 n=",nf21)), col=c("black", "red","green"),lty=1:1, cex=0.8)
title("Number of students missing each Prelab")
allVideo = data.frame(matrix(ncol = 0,nrow=3))
j18 = nrow(videof18)
j19 = nrow(videof19)
j21 = nrow(videof21)
#f19 has the least number of columns, I need more data. The last two columns are averages
for (i in 1:(ncol(videof19)-2)){
allVideo[paste("video",i)] = c(
videof18[j18,i+1],
videof19[j19,i+1],
videof21[j21,i+6]
)
}
row.names(allVideo) = c("Fall18","Fall19","Fall21")
tAllVideo = t(allVideo)
matplot(tAllVideo,type="l",xlab="Video instance",ylab="Number students not watching it",main="Students who do not watch that video")
legend("topright",legend = colnames(tAllVideo),col=1:3,lty=1:3)
par(mfrow=c(1,3),
oma = c(5,4,0,0) + 0.1,
mar = c(0,0,1,1) + 0.1)
hist(videof18$TotalMissed,xlim = c(0,50),ylim=c(0,140),main="Fall18",xlab="Number of videos missed",ylab="Number of students")
hist(videof19$TotalMissed,xlim = c(0,50),ylim=c(0,140),main="Fall19",xlab="Number of videos missed",ylab="Number of students")
hist(videof21$VideosMissed,xlim = c(0,50),ylim=c(0,140),main="Fall21",xlab="Number of videos missed",ylab="Number of students")
plot( gradesf18$Exam.1..335345., gradesf18$Unposted.Final.Score ,type='p',xlab='Exam1/100',ylab='Final Grade/100',main='Final grade vs Exam1')
abline(lm(gradesf18$Unposted.Final.Score ~ gradesf18$Exam.1..335345.))
points( gradesf19$Open.Ended.Written.Exam.1..816325., gradesf19$Unposted.Final.Score,col="red")
abline(lm(gradesf19$Unposted.Final.Score ~ gradesf19$Open.Ended.Written.Exam.1..816325.),col="red")
points( gradesf21$Exam..1..2161998., gradesf21$Unposted.Final.Score,col="green")
#abline(lm(
# gradesf21$Unposted.Final.Score[!is.na(gradesf21$Exam..1..2161998.)] ~
# gradesf21$Exam..1..2161998.[!is.na(gradesf21$Exam..1..2161998.)]/25*100),col="green")
legend("bottomright",legend = c("F18","F19","F21"),col=c("black","red","green"),lty=1:1, cex=0.8)
plot( gradesf18$Exam.2..358394., gradesf18$Unposted.Final.Score,type='p',xlab='Exam2/100',ylab='Final Grade/100',main='Final grade vs Exam2')
abline(lm( gradesf18$Unposted.Final.Score ~ gradesf18$Exam.2..358394.))
points( gradesf19$Open.Ended.Exam.2..836125., gradesf19$Unposted.Final.Score, col="red")
abline(lm( gradesf19$Unposted.Final.Score ~ gradesf19$Open.Ended.Exam.2..836125. ),col="red")
points( gradesf21$Exam..2..2171776.,gradesf21$Unposted.Final.Score, col="green")
abline(lm( gradesf21$Unposted.Final.Score ~ gradesf21$Exam..2..2171776.), col="green")
legend("bottomright",legend = c("F18","F19","F21"),col=c("black","red","green"),lty=1:1, cex=0.8)
plot( gradesf18$Exam.3..395005., gradesf18$Unposted.Final.Score, type='p',xlab='Exam3/100',ylab='Final Grade/100',main='Final grade vs Exam3')
abline(lm( gradesf18$Unposted.Final.Score ~ gradesf18$Exam.3..395005.))
points( gradesf19$Open.Ended.Exam.3..875116., gradesf19$Unposted.Final.Score, col="red")
abline( lm( gradesf19$Unposted.Final.Score ~ gradesf19$Open.Ended.Exam.3..875116.),col="red")
points( gradesf21$Exam..3..2184781., gradesf21$Unposted.Final.Score, col="green")
abline( lm( gradesf21$Unposted.Final.Score ~ gradesf21$Exam..3..2184781.),col="green")
legend("bottomright",legend = c("F18","F19","F21"),col=c("black","red","green"),lty=1:1, cex=0.8)
plot( gradesf18$Final.exam..408510., gradesf18$Unposted.Final.Score, type='p',xlab='Final Exam/100',ylab='Final Grade/100',main='Final grade vs Final exam',ylim=c(50,100))
abline( lm( gradesf18$Unposted.Final.Score ~ gradesf18$Final.exam..408510. ))
points( gradesf19$Final.exam.Unposted.Current.Score, gradesf19$Unposted.Final.Score, col="red")
abline( lm( gradesf19$Unposted.Final.Score ~ gradesf19$Final.exam.Unposted.Current.Score), col="red")
points( gradesf21$Final.Written.Exam.Current.Score, gradesf21$Unposted.Current.Score, col="green")
abline(lm( gradesf21$Unposted.Final.Score ~ gradesf21$Final.Written.Exam.Current.Score),col="green")
legend("bottomright",legend = c("F18","F19","F21"),col=c("black","red","green"),lty=1:1, cex=0.8)
f18hw$ave = rowMeans(f18hw)
f19hw$ave = rowMeans(f19hw)
f21hw$ave = rowMeans(f21hw)
plot(f18hw$ave, gradesf18$Unposted.Final.Score,type='p', xlab='Ave HW/100',ylab='Final Grade/100',main='Final Grade vs Average Homework',ylim=c(0,100))
abline( lm(gradesf18$Unposted.Final.Score ~ f18hw$ave ))
points(f19hw$ave, gradesf19$Unposted.Current.Score,col="red")
abline( lm(gradesf19$Unposted.Final.Score ~ f19hw$ave ),col="red")
points(f21hw$ave, gradesf21$Unposted.Current.Score,col="green")
abline( lm(gradesf21$Unposted.Final.Score ~ f21hw$ave ),col="green")
legend("bottomright",legend = c("F18","F19","F21"),col=c("black","red","green"),lty=1:1, cex=0.8)
f18report$ave = rowMeans(f18report)
f19report$ave = rowMeans(f19report)
f21report$ave = rowMeans(f21report)
plot(f18report$ave, gradesf18$Unposted.Final.Score,type='p', xlab='Ave Lab Report/100',ylab='Final Grade/100',main='Final Grade vs Average Lab Report',ylim=c(0,100))
abline( lm(gradesf18$Unposted.Final.Score ~ f18report$ave ))
points(f19report$ave, gradesf19$Unposted.Current.Score,col="red")
abline( lm(gradesf19$Unposted.Final.Score ~ f19report$ave ),col="red")
points(f21report$ave, gradesf21$Unposted.Current.Score,col="green")
abline( lm(gradesf21$Unposted.Final.Score ~ f21report$ave ),col="green")
legend("bottomright",legend = c("F18","F19","F21"),col=c("black","red","green"),lty=1:1, cex=0.8)
It looks like in 2018 we didn’t require the 90% prelab score to to be in the lab. This shows as Fall2018 has the prelab averages all over the place. Fall2019 and Fall2021 however shows pretty much everyone with an average above 90%.
plot( gradesf18$Lab..Prelab.Quiz.Unposted.Final.Score, gradesf18$Unposted.Final.Score,type='p', xlab='Ave Prelab /100',ylab='Final Grade/100',main='Final Grade vs Average Prelab',ylim=c(0,100) )
abline(lm( gradesf18$Unposted.Final.Score ~ gradesf18$Lab..Prelab.Quiz.Unposted.Final.Score))
points(gradesf19$Lab..Prelab.Quiz.Unposted.Final.Score, gradesf19$Unposted.Current.Score,col="red")
abline( lm(gradesf19$Unposted.Final.Score ~ gradesf19$Lab..Prelab.Quiz.Unposted.Final.Score ),col="red")
points(gradesf21$Pre.Lab.Assignments.Unposted.Final.Score, gradesf21$Unposted.Current.Score,col="green")
abline( lm(gradesf21$Unposted.Final.Score ~ gradesf21$Pre.Lab.Assignments.Unposted.Final.Score ),col="green")
legend("bottomright",legend = c("F18","F19","F21"),col=c("black","red","green"),lty=1:1, cex=0.8)
getMeanAndSD = function(df,score){
results = data.frame(matrix(ncol=1,nrow=5))
i = 1
for (let in c("A","B","C","D","F")){
thisMean = sprintf("%.2f", mean( df[which(grepl(let,df$Unposted.Final.Grade)),][[score]], na.rm = TRUE))
thisSD = sprintf("%.1f", sd( df[which(grepl(let,df$Unposted.Final.Grade)),][[score]], na.rm = TRUE))
results[i,1] = paste(thisMean,'+/-',thisSD)
i=i+1
}
return(results)
}
f18ave = data.frame(matrix(ncol=0,nrow = 5))
f18ave["Written Exams "] = getMeanAndSD(gradesf18,"Science.Practice.Exercises.Unposted.Final.Score")
f18ave["Final Exam"] = getMeanAndSD(gradesf18,"Final.exam.Unposted.Current.Score")
f18ave["Milestone "] = getMeanAndSD(gradesf18,"Milestones.Unposted.Current.Score")
f18ave["HW "] = getMeanAndSD(gradesf18,"Homework.Current.Score")
f18ave["Lab reports"] = getMeanAndSD(gradesf18,"Lab..Reporting.Unposted.Current.Score")
f18ave["Miss Preclass"] = getMeanAndSD(gradesf18,"missPreclass")
f18ave["Miss Prelab"] = getMeanAndSD(gradesf18,"missPrelab")
row.names(f18ave)=c("A students","B students","C students","D students","F students")
knitr::kable(f18ave,caption="Fall 2018: Average +/- Standard Deviation Based on Grade Performance")
Written Exams | Final Exam | Milestone | HW | Lab reports | Miss Preclass | Miss Prelab | |
---|---|---|---|---|---|---|---|
A students | 81.51 +/- 6.6 | 87.55 +/- 6.0 | 100.00 +/- 0.0 | 97.69 +/- 2.5 | 92.12 +/- 3.8 | 1.58 +/- 1.9 | 0.04 +/- 0.3 |
B students | 62.77 +/- 9.8 | 74.05 +/- 7.3 | 98.82 +/- 3.0 | 94.33 +/- 5.1 | 88.05 +/- 5.5 | 2.99 +/- 2.7 | 0.12 +/- 0.4 |
C students | 48.98 +/- 7.2 | 61.31 +/- 7.0 | 85.42 +/- 10.3 | 87.27 +/- 7.3 | 84.94 +/- 7.5 | 3.17 +/- 2.5 | 0.08 +/- 0.3 |
D students | 43.92 +/- 11.3 | 59.91 +/- 6.3 | 63.75 +/- 13.1 | 79.92 +/- 14.8 | 71.19 +/- 10.8 | 5.25 +/- 3.9 | 1.00 +/- 1.2 |
F students | 35.88 +/- 10.7 | NaN +/- NA | 46.05 +/- 25.3 | 62.19 +/- 17.2 | 59.30 +/- 14.9 | 14.40 +/- 5.2 | 2.40 +/- 1.5 |
f19ave = data.frame(matrix(ncol=0,nrow = 5))
f19ave["Written Exams "] = getMeanAndSD(gradesf19,"Open.Ended.Written.Exams.Unposted.Final.Score")
f19ave["Final Exam"] = getMeanAndSD(gradesf19,"Final.exam.Unposted.Final.Score")
f19ave["Milestone "] = getMeanAndSD(gradesf19,"Milestones.Unposted.Current.Score")
f19ave["HW "] = getMeanAndSD(gradesf19,"Homework.Current.Score")
f19ave["Lab reports"] = getMeanAndSD(gradesf19,"Lab..Reporting.Unposted.Current.Score")
f19ave["Miss Preclass"] = getMeanAndSD(gradesf19,"missPreclass")
f19ave["Miss Prelab"] = getMeanAndSD(gradesf19,"missPrelab")
row.names(f19ave)=c("A students","B students","C students","D students","F students")
knitr::kable(f19ave,caption="Fall 2019: Average +/- Standard Deviation Based on Grade Performance")
Written Exams | Final Exam | Milestone | HW | Lab reports | Miss Preclass | Miss Prelab | |
---|---|---|---|---|---|---|---|
A students | 84.14 +/- 6.0 | 82.22 +/- 8.0 | 100.00 +/- 0.0 | 98.25 +/- 1.6 | 88.44 +/- 6.6 | 1.77 +/- 1.9 | 0.07 +/- 0.3 |
B students | 64.24 +/- 9.7 | 64.08 +/- 9.4 | 99.74 +/- 1.1 | 93.92 +/- 4.8 | 81.71 +/- 9.5 | 2.33 +/- 2.0 | 0.08 +/- 0.3 |
C students | 47.63 +/- 10.8 | 46.57 +/- 13.8 | 92.34 +/- 8.6 | 91.34 +/- 6.4 | 73.07 +/- 11.8 | 3.00 +/- 2.7 | 0.09 +/- 0.4 |
D students | 37.11 +/- 12.5 | 45.38 +/- 7.8 | 70.83 +/- 10.2 | 77.24 +/- 14.3 | 57.39 +/- 23.2 | 4.00 +/- 4.0 | 0.33 +/- 0.8 |
F students | 33.85 +/- 12.9 | 9.96 +/- 19.9 | 68.75 +/- 33.8 | 64.80 +/- 16.5 | 41.30 +/- 16.4 | 12.25 +/- 5.9 | 1.75 +/- 3.5 |
f21ave = data.frame(matrix(ncol=0,nrow = 5))
f21ave["Written Exams "] = getMeanAndSD(gradesf21,"Open.Ended.Semester.Exams.Unposted.Final.Score")
f21ave["Final Exam"] = getMeanAndSD(gradesf21,"Final.Written.Exam.Unposted.Final.Score")
f21ave["Milestone "] = getMeanAndSD(gradesf21,"Milestones.Unposted.Current.Score")
f21ave["HW "] = getMeanAndSD(gradesf21,"Homework.Current.Score")
f21ave["Lab reports"] = getMeanAndSD(gradesf21,"Lab.Reports.Unposted.Current.Score")
f21ave["Miss Preclass"] = getMeanAndSD(gradesf21,"missPreclass")
f21ave["Miss Prelab"] = getMeanAndSD(gradesf21,"missPrelab")
f21ave["Miss Videos"] = getMeanAndSD(gradesf21,"VideosMissed")
row.names(f21ave)=c("A students","B students","C students","D students","F students")
knitr::kable(f21ave,caption="Fall 2021: Average +/- Standard Deviation Based on Grade Performance")
Written Exams | Final Exam | Milestone | HW | Lab reports | Miss Preclass | Miss Prelab | Miss Videos | |
---|---|---|---|---|---|---|---|---|
A students | 86.60 +/- 6.8 | 78.75 +/- 11.3 | 99.66 +/- 1.3 | 96.71 +/- 3.5 | 91.30 +/- 4.7 | 1.84 +/- 1.9 | 0.01 +/- 0.1 | 8.41 +/- 11.5 |
B students | 70.36 +/- 8.1 | 58.90 +/- 11.5 | 98.57 +/- 3.2 | 91.26 +/- 5.1 | 78.68 +/- 10.2 | 2.91 +/- 2.2 | 0.07 +/- 0.3 | 19.09 +/- 15.9 |
C students | 54.11 +/- 13.3 | 46.36 +/- 13.8 | 85.61 +/- 9.4 | 82.54 +/- 9.6 | 65.32 +/- 13.6 | 4.39 +/- 2.6 | 0.12 +/- 0.3 | 25.64 +/- 15.9 |
D students | 45.06 +/- 7.7 | 44.44 +/- 7.8 | 66.00 +/- 17.0 | 73.20 +/- 10.3 | 52.70 +/- 18.1 | 5.50 +/- 3.7 | 0.30 +/- 0.7 | 35.50 +/- 18.7 |
F students | 34.22 +/- 20.1 | 17.25 +/- 27.5 | 30.00 +/- 19.6 | 52.11 +/- 26.7 | 40.13 +/- 21.2 | 9.88 +/- 5.1 | 1.50 +/- 1.9 | 44.38 +/- 21.3 |
Missing four videos is approximately equivalent to missing one day of class
#install.packages("ggpubr")
library(ggpubr)
plotGGbox = function(df,myx,myy,mytitle,myylab){
maxy = max(df[[myy]])
ggboxplot(df, x = myx, y = myy,
title = mytitle,
color = myx, add = "jitter", legend="none",ylab = myylab) + rotate_x_text(angle = 45) +
geom_hline( yintercept = mean(df[[myy]]), linetype = 2) +
stat_compare_means(method = "anova", label.y = maxy*1.10) +
stat_compare_means(label = "p.format", size=2.5, method = "t.test", ref.group = ".all.",label.y = maxy*1.05)
}
gradesf18 = gradesf18[order(gradesf18$simpleLetter),]
gradesf19 = gradesf19[order(gradesf19$simpleLetter),]
gradesf21 = gradesf21[order(gradesf21$simpleLetter),]
#Written exams
print( plotGGbox(gradesf18,"simpleLetter","Science.Practice.Exercises.Unposted.Final.Score","Fall18: Written Semester Exams:Wrapped Letters","Average Semester Exams"))
print( plotGGbox(gradesf18,"Unposted.Final.Grade","Science.Practice.Exercises.Unposted.Final.Score","Fall18: Written Semester Exams:All Letters","Average Semester Exams"))
print( plotGGbox(gradesf19,"simpleLetter","Open.Ended.Written.Exams.Unposted.Final.Score","Fall19: Written Semester Exams:Wrapped Letters","Average Semester Exams"))
print(plotGGbox(gradesf19,"Unposted.Final.Grade","Open.Ended.Written.Exams.Unposted.Final.Score","Fall19: Written Semester Exams:All Letters","Average Semester Exams"))
print( plotGGbox(gradesf18,"simpleLetter","Milestones.Unposted.Current.Score","Fall18: Milestone Avg","Avg Milestone grade") )
print( plotGGbox(gradesf18,"simpleLetter","Homework.Current.Score","Fall18: Homework Avg","Avg Homework grade") )
print( plotGGbox(gradesf18,"simpleLetter","Lab..Reporting.Unposted.Current.Score","Fall18: Lab reports Avg","Avg Lab reports grade") )
print( plotGGbox(gradesf18,"simpleLetter","missPreclass","Fall18: Missed preclass instances","Missed preclass") )
Too often, educators conjugate students as “they” as if they were a homogeneous group. When trying to use a finer granularity we may label “good students” and “bad students” based on performance. However, even among these two groups the charactersitics are not similar. In fact, as instructors we want to identify the group of students that we can help the most. I propose that we cluster students along two axis, performance and effort, yielding at least four different groups:
WE-LP (wrong/low effor and low performance)
HE-LP (high effort and low performance)
LE-AP (low/lazy effort - acceptable performance)
HE-AP (high effort - acceptable performance)
We have several indicators that when combined can be used to measure effort. We will start simple and look at what Canvas reports as Canvas participation