this is just me messing around with ChatGPT and seeing what is
out there, it lacks the rigor i would associate with my own work; but, a
useful exploration of a interest
The purpose is to familiarize myself with topics i wish to dive deeper into my own private analysis
setwd("/Users/isaiahmireles/Desktop/Misconceptions")
cohorts <- read.csv("cohorts.csv")
library(tidyverse)
## Warning: package 'dplyr' was built under R version 4.4.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.2.0 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 4.0.0 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.1.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
items <- cohorts |>
filter(term == "F23",
exam == "Midterm") |>
pivot_longer(
cols = matches("^Q\\d+$"),
names_to = "question",
values_to = "correct"
) |>
mutate(
question = factor(
question,
levels = paste0("Q", 1:34)
)
)
items |>
group_by(question) |>
summarise(p_correct = mean(correct, na.rm = TRUE)) |>
ggplot(aes(x = question, y = p_correct)) +
geom_col(fill = "steelblue") +
coord_cartesian(ylim = c(0, 1)) +
labs(
title = "Item Difficulty: F23 Midterm",
x = "Question",
y = "Proportion Correct"
) +
theme_minimal()
items |>
ggplot(aes(x = question, y = student_id,
fill = factor(correct))) +
geom_tile() +
scale_fill_manual(
values = c("0" = "tomato", "1" = "seagreen"),
na.value = "grey85"
) +
labs(
title = "Student Response Heatmap",
x = "Question",
y = "Student",
fill = "Correct"
) +
theme_minimal() +
theme(
axis.text.y = element_blank(),
axis.ticks.y = element_blank()
)
cohorts |>
filter(term == "F23",
exam == "Midterm",
version == "A") |>
select(matches("^Q\\d+$")) |>
summarise(
across(
everything(),
~ cor(
.x,
rowSums(pick(everything()), na.rm = TRUE) - .x,
use = "complete.obs"
)
)
) |>
pivot_longer(
everything(),
names_to = "question",
values_to = "item_rest_cor"
) |>
ggplot(aes(
x = reorder(question, item_rest_cor),
y = item_rest_cor
)) +
geom_col(fill = "steelblue") +
coord_flip() +
labs(
title = "Corrected Item-Total Correlations",
x = "Question",
y = "Correlation"
) +
theme_minimal()
library(tidyverse)
library(igraph)
##
## Attaching package: 'igraph'
## The following objects are masked from 'package:lubridate':
##
## %--%, union
## The following objects are masked from 'package:dplyr':
##
## as_data_frame, groups, union
## The following objects are masked from 'package:purrr':
##
## compose, simplify
## The following object is masked from 'package:tidyr':
##
## crossing
## The following object is masked from 'package:tibble':
##
## as_data_frame
## The following objects are masked from 'package:stats':
##
## decompose, spectrum
## The following object is masked from 'package:base':
##
## union
library(ggraph)
X <- cohorts |>
filter(
term == "S24",
exam == "Midterm",
version == "AB"
) |>
select(matches("^Q\\d+$"))
# Binary item correlation matrix
R <- cor(X, use = "pairwise.complete.obs")
# Convert matrix to network edges
edges <- as.data.frame(as.table(R)) |>
rename(from = Var1, to = Var2, weight = Freq) |>
filter(
as.integer(from) < as.integer(to),
abs(weight) >= 0.20
)
nodes <- tibble(
name = names(X),
p_correct = colMeans(X, na.rm = TRUE)
)
g <- graph_from_data_frame(
edges,
directed = FALSE,
vertices = nodes
)
ggraph(g, layout = "fr") +
geom_edge_link(aes(width = abs(weight)),
alpha = 0.4) +
geom_node_point(aes(size = p_correct),
color = "steelblue") +
geom_node_text(aes(label = name), repel = TRUE) +
theme_graph()
## Warning: The `trans` argument of `continuous_scale()` is deprecated as of ggplot2 3.5.0.
## ℹ Please use the `transform` argument instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
library(tidyverse)
library(mirt)
## Warning: package 'mirt' was built under R version 4.4.3
## Loading required package: stats4
## Loading required package: lattice
# Fit Rasch model
model <- mirt(
data = X,
model = 1,
itemtype = "Rasch",
verbose = FALSE
)
# Extract Q3 residual correlation matrix
Q3 <- residuals(model, type = "Q3")
## Q3 summary statistics:
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## -0.251 -0.088 -0.022 -0.020 0.037 0.472
##
## Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 Q10
## Q1 1.000 0.252 0.009 0.016 -0.094 -0.136 0.248 0.006 -0.081 0.053
## Q2 0.252 1.000 0.305 -0.106 0.012 -0.057 -0.037 0.009 0.134 0.075
## Q3 0.009 0.305 1.000 -0.138 -0.063 0.051 -0.061 0.007 0.049 0.149
## Q4 0.016 -0.106 -0.138 1.000 -0.228 -0.244 -0.039 0.059 -0.001 0.101
## Q5 -0.094 0.012 -0.063 -0.228 1.000 0.018 0.069 -0.045 -0.027 -0.077
## Q6 -0.136 -0.057 0.051 -0.244 0.018 1.000 0.126 -0.188 -0.057 -0.179
## Q7 0.248 -0.037 -0.061 -0.039 0.069 0.126 1.000 0.031 -0.039 -0.025
## Q8 0.006 0.009 0.007 0.059 -0.045 -0.188 0.031 1.000 -0.007 0.069
## Q9 -0.081 0.134 0.049 -0.001 -0.027 -0.057 -0.039 -0.007 1.000 0.119
## Q10 0.053 0.075 0.149 0.101 -0.077 -0.179 -0.025 0.069 0.119 1.000
## Q11 -0.071 -0.079 -0.118 -0.063 0.097 -0.028 -0.034 0.121 0.192 0.047
## Q12 0.014 0.017 -0.113 -0.058 -0.080 -0.053 -0.096 0.028 0.087 0.042
## Q13 -0.141 -0.155 0.098 0.169 -0.099 0.085 -0.068 0.003 -0.145 -0.077
## Q14 -0.057 0.038 0.010 -0.089 0.012 -0.022 -0.071 0.013 0.096 -0.177
## Q15 -0.021 -0.134 -0.028 -0.007 -0.076 0.061 0.120 -0.105 -0.126 -0.228
## Q16 -0.002 -0.004 -0.204 -0.019 -0.128 -0.118 -0.059 -0.030 0.199 -0.045
## Q17 0.057 0.056 -0.022 0.117 -0.176 -0.124 -0.035 0.090 -0.090 0.036
## Q18 -0.131 -0.140 0.069 0.074 -0.051 -0.073 -0.108 0.054 0.029 -0.059
## Q19 0.030 -0.192 -0.001 0.029 0.012 -0.049 -0.084 -0.015 -0.038 -0.112
## Q20 -0.121 -0.128 -0.017 -0.008 0.055 -0.059 -0.060 0.094 0.132 0.099
## Q21 -0.134 -0.054 -0.033 0.076 0.140 -0.142 -0.104 -0.131 -0.097 -0.062
## Q22 -0.034 0.084 -0.069 -0.053 -0.041 -0.179 0.059 -0.036 -0.028 -0.146
## Q23 -0.020 -0.102 0.045 0.017 0.018 0.112 -0.127 -0.100 -0.133 -0.013
## Q24 0.121 -0.004 0.050 -0.217 0.062 -0.033 0.020 -0.114 -0.012 -0.122
## Q25 -0.054 -0.176 0.029 -0.076 -0.045 0.076 0.116 0.049 -0.022 -0.081
## Q26 -0.109 -0.010 0.000 -0.162 0.117 0.079 -0.049 -0.017 0.022 -0.073
## Q27 -0.126 -0.030 0.090 -0.118 0.067 0.242 0.067 -0.009 0.171 0.087
## Q28 0.102 0.011 0.053 0.062 -0.057 -0.178 -0.078 -0.123 -0.048 0.151
## Q29 -0.127 -0.048 0.000 -0.010 -0.179 0.172 -0.001 -0.161 0.049 -0.031
## Q30 0.103 0.235 0.097 0.002 -0.106 -0.071 -0.059 0.036 0.020 0.108
## Q31 0.083 0.004 -0.003 -0.194 0.047 -0.015 0.030 0.247 -0.013 0.024
## Q32 0.080 0.008 -0.195 -0.112 -0.129 -0.051 0.031 -0.138 -0.105 -0.029
## Q33 -0.003 0.027 -0.181 -0.144 0.053 0.063 -0.054 -0.218 -0.018 0.011
## Q34 -0.079 0.023 -0.048 0.032 -0.047 -0.053 -0.054 -0.070 -0.114 0.033
## Q11 Q12 Q13 Q14 Q15 Q16 Q17 Q18 Q19 Q20
## Q1 -0.071 0.014 -0.141 -0.057 -0.021 -0.002 0.057 -0.131 0.030 -0.121
## Q2 -0.079 0.017 -0.155 0.038 -0.134 -0.004 0.056 -0.140 -0.192 -0.128
## Q3 -0.118 -0.113 0.098 0.010 -0.028 -0.204 -0.022 0.069 -0.001 -0.017
## Q4 -0.063 -0.058 0.169 -0.089 -0.007 -0.019 0.117 0.074 0.029 -0.008
## Q5 0.097 -0.080 -0.099 0.012 -0.076 -0.128 -0.176 -0.051 0.012 0.055
## Q6 -0.028 -0.053 0.085 -0.022 0.061 -0.118 -0.124 -0.073 -0.049 -0.059
## Q7 -0.034 -0.096 -0.068 -0.071 0.120 -0.059 -0.035 -0.108 -0.084 -0.060
## Q8 0.121 0.028 0.003 0.013 -0.105 -0.030 0.090 0.054 -0.015 0.094
## Q9 0.192 0.087 -0.145 0.096 -0.126 0.199 -0.090 0.029 -0.038 0.132
## Q10 0.047 0.042 -0.077 -0.177 -0.228 -0.045 0.036 -0.059 -0.112 0.099
## Q11 1.000 0.104 0.030 0.113 -0.109 0.210 -0.079 0.051 -0.020 0.139
## Q12 0.104 1.000 0.170 -0.101 -0.036 0.121 0.154 -0.060 0.011 0.123
## Q13 0.030 0.170 1.000 -0.039 0.012 -0.029 -0.158 0.067 0.104 0.095
## Q14 0.113 -0.101 -0.039 1.000 0.182 -0.090 -0.002 -0.242 -0.146 -0.104
## Q15 -0.109 -0.036 0.012 0.182 1.000 -0.042 -0.046 -0.056 -0.146 -0.184
## Q16 0.210 0.121 -0.029 -0.090 -0.042 1.000 -0.141 0.028 0.137 0.119
## Q17 -0.079 0.154 -0.158 -0.002 -0.046 -0.141 1.000 -0.088 -0.015 -0.135
## Q18 0.051 -0.060 0.067 -0.242 -0.056 0.028 -0.088 1.000 0.325 0.270
## Q19 -0.020 0.011 0.104 -0.146 -0.146 0.137 -0.015 0.325 1.000 0.390
## Q20 0.139 0.123 0.095 -0.104 -0.184 0.119 -0.135 0.270 0.390 1.000
## Q21 0.036 0.023 0.038 0.007 -0.073 0.002 -0.097 0.072 -0.020 -0.079
## Q22 -0.099 0.099 -0.053 0.066 0.021 0.034 0.064 -0.251 -0.054 -0.028
## Q23 -0.106 -0.020 0.093 0.115 -0.052 -0.066 -0.080 0.043 -0.011 -0.025
## Q24 0.013 -0.130 -0.156 0.148 0.017 0.067 -0.109 -0.071 -0.083 -0.085
## Q25 -0.005 -0.012 0.058 -0.041 -0.048 -0.084 -0.086 0.078 0.149 0.164
## Q26 0.176 -0.143 -0.039 -0.094 -0.109 0.070 -0.124 -0.015 0.020 0.086
## Q27 -0.065 -0.105 0.012 0.001 -0.044 -0.110 -0.080 0.054 -0.021 0.064
## Q28 -0.147 -0.218 -0.149 -0.048 -0.039 0.022 -0.110 0.174 0.044 -0.126
## Q29 -0.022 0.119 -0.075 -0.002 -0.011 0.014 0.019 -0.225 -0.178 -0.143
## Q30 -0.119 -0.082 -0.233 0.029 -0.205 -0.119 0.472 -0.021 -0.062 -0.191
## Q31 -0.100 -0.043 -0.077 -0.108 -0.079 0.024 -0.138 0.041 -0.088 -0.008
## Q32 -0.080 -0.035 -0.059 -0.090 0.078 0.028 0.018 -0.147 -0.027 -0.094
## Q33 -0.186 -0.003 0.037 -0.137 0.145 0.011 0.040 -0.011 0.043 -0.029
## Q34 0.010 0.092 -0.025 -0.093 -0.047 -0.110 0.097 0.026 -0.108 -0.028
## Q21 Q22 Q23 Q24 Q25 Q26 Q27 Q28 Q29 Q30
## Q1 -0.134 -0.034 -0.020 0.121 -0.054 -0.109 -0.126 0.102 -0.127 0.103
## Q2 -0.054 0.084 -0.102 -0.004 -0.176 -0.010 -0.030 0.011 -0.048 0.235
## Q3 -0.033 -0.069 0.045 0.050 0.029 0.000 0.090 0.053 0.000 0.097
## Q4 0.076 -0.053 0.017 -0.217 -0.076 -0.162 -0.118 0.062 -0.010 0.002
## Q5 0.140 -0.041 0.018 0.062 -0.045 0.117 0.067 -0.057 -0.179 -0.106
## Q6 -0.142 -0.179 0.112 -0.033 0.076 0.079 0.242 -0.178 0.172 -0.071
## Q7 -0.104 0.059 -0.127 0.020 0.116 -0.049 0.067 -0.078 -0.001 -0.059
## Q8 -0.131 -0.036 -0.100 -0.114 0.049 -0.017 -0.009 -0.123 -0.161 0.036
## Q9 -0.097 -0.028 -0.133 -0.012 -0.022 0.022 0.171 -0.048 0.049 0.020
## Q10 -0.062 -0.146 -0.013 -0.122 -0.081 -0.073 0.087 0.151 -0.031 0.108
## Q11 0.036 -0.099 -0.106 0.013 -0.005 0.176 -0.065 -0.147 -0.022 -0.119
## Q12 0.023 0.099 -0.020 -0.130 -0.012 -0.143 -0.105 -0.218 0.119 -0.082
## Q13 0.038 -0.053 0.093 -0.156 0.058 -0.039 0.012 -0.149 -0.075 -0.233
## Q14 0.007 0.066 0.115 0.148 -0.041 -0.094 0.001 -0.048 -0.002 0.029
## Q15 -0.073 0.021 -0.052 0.017 -0.048 -0.109 -0.044 -0.039 -0.011 -0.205
## Q16 0.002 0.034 -0.066 0.067 -0.084 0.070 -0.110 0.022 0.014 -0.119
## Q17 -0.097 0.064 -0.080 -0.109 -0.086 -0.124 -0.080 -0.110 0.019 0.472
## Q18 0.072 -0.251 0.043 -0.071 0.078 -0.015 0.054 0.174 -0.225 -0.021
## Q19 -0.020 -0.054 -0.011 -0.083 0.149 0.020 -0.021 0.044 -0.178 -0.062
## Q20 -0.079 -0.028 -0.025 -0.085 0.164 0.086 0.064 -0.126 -0.143 -0.191
## Q21 1.000 0.010 0.106 0.021 -0.131 -0.094 -0.103 -0.026 0.003 -0.047
## Q22 0.010 1.000 -0.118 0.037 -0.064 -0.058 -0.225 -0.007 0.007 -0.011
## Q23 0.106 -0.118 1.000 -0.081 -0.050 -0.113 -0.018 -0.086 -0.009 -0.124
## Q24 0.021 0.037 -0.081 1.000 -0.158 -0.076 -0.246 0.053 -0.189 -0.134
## Q25 -0.131 -0.064 -0.050 -0.158 1.000 -0.018 0.038 -0.153 0.148 -0.108
## Q26 -0.094 -0.058 -0.113 -0.076 -0.018 1.000 0.067 -0.006 0.047 -0.116
## Q27 -0.103 -0.225 -0.018 -0.246 0.038 0.067 1.000 0.038 -0.009 0.143
## Q28 -0.026 -0.007 -0.086 0.053 -0.153 -0.006 0.038 1.000 -0.070 0.188
## Q29 0.003 0.007 -0.009 -0.189 0.148 0.047 -0.009 -0.070 1.000 0.000
## Q30 -0.047 -0.011 -0.124 -0.134 -0.108 -0.116 0.143 0.188 0.000 1.000
## Q31 0.022 -0.120 0.051 -0.105 -0.020 0.026 0.134 -0.050 -0.025 0.027
## Q32 -0.191 -0.028 0.024 -0.208 -0.014 -0.023 0.019 -0.003 -0.020 0.084
## Q33 -0.048 -0.084 0.040 -0.167 0.087 -0.003 -0.037 0.026 -0.035 -0.085
## Q34 -0.014 -0.194 -0.195 -0.053 0.028 -0.009 -0.039 -0.150 0.026 -0.032
## Q31 Q32 Q33 Q34
## Q1 0.083 0.080 -0.003 -0.079
## Q2 0.004 0.008 0.027 0.023
## Q3 -0.003 -0.195 -0.181 -0.048
## Q4 -0.194 -0.112 -0.144 0.032
## Q5 0.047 -0.129 0.053 -0.047
## Q6 -0.015 -0.051 0.063 -0.053
## Q7 0.030 0.031 -0.054 -0.054
## Q8 0.247 -0.138 -0.218 -0.070
## Q9 -0.013 -0.105 -0.018 -0.114
## Q10 0.024 -0.029 0.011 0.033
## Q11 -0.100 -0.080 -0.186 0.010
## Q12 -0.043 -0.035 -0.003 0.092
## Q13 -0.077 -0.059 0.037 -0.025
## Q14 -0.108 -0.090 -0.137 -0.093
## Q15 -0.079 0.078 0.145 -0.047
## Q16 0.024 0.028 0.011 -0.110
## Q17 -0.138 0.018 0.040 0.097
## Q18 0.041 -0.147 -0.011 0.026
## Q19 -0.088 -0.027 0.043 -0.108
## Q20 -0.008 -0.094 -0.029 -0.028
## Q21 0.022 -0.191 -0.048 -0.014
## Q22 -0.120 -0.028 -0.084 -0.194
## Q23 0.051 0.024 0.040 -0.195
## Q24 -0.105 -0.208 -0.167 -0.053
## Q25 -0.020 -0.014 0.087 0.028
## Q26 0.026 -0.023 -0.003 -0.009
## Q27 0.134 0.019 -0.037 -0.039
## Q28 -0.050 -0.003 0.026 -0.150
## Q29 -0.025 -0.020 -0.035 0.026
## Q30 0.027 0.084 -0.085 -0.032
## Q31 1.000 -0.002 -0.146 0.092
## Q32 -0.002 1.000 0.262 0.030
## Q33 -0.146 0.262 1.000 -0.021
## Q34 0.092 0.030 -0.021 1.000
# Convert matrix to long format
Q3_long <- as.data.frame(Q3) |>
rownames_to_column("Item1") |>
pivot_longer(
cols = -Item1,
names_to = "Item2",
values_to = "Q3"
)
# Plot
Q3_long |>
ggplot(aes(x = Item1, y = Item2, fill = Q3)) +
geom_tile() +
scale_fill_gradient2(
low = "tomato",
mid = "white",
high = "steelblue",
midpoint = 0
) +
coord_equal() +
labs(
title = "IRT Residual Correlation Matrix",
x = "Question",
y = "Question",
fill = "Q3"
) +
theme_minimal()