setwd("/Users/isaiahmireles/Desktop/Misconceptions")
cohorts <- read.csv("cohorts.csv")
cohorts$exam <- factor(cohorts$exam)
library(tidyverse)notice we have a hierarchical structure to our data.
Repeated obs. occur at the student level
Midterm and Finalexams vary in std. ct
Notice students after taking the Midterm , drop
S10
# Std. dropoff (After Data Clean Filter)
cohorts |>
group_by(term, exam) |>
# careful w/ summarize preserving grouping
summarize(
std_ct = n(),
.groups = "drop"
) |>
pivot_wider(
names_from = exam,
values_from = std_ct
) |>
mutate(dropoff = Final - Midterm)F23PPQthe following data is the percent
of students that got item i correct
pct which defines the
percent-score obtained by student j# percent per q dat
PPQ <-
cohorts |>
pivot_longer(
# select starts w/ Q, then 1 digit
cols = matches("^Q\\d+$"),
# grab q,
names_to = "question",
values_to = "correct"
) |>
group_by(term, exam, question) |>
# ct std (matches above)
summarize(
n_students = n(),
PPQ = mean(correct)
) # Data split PPQ
PPQ_list <- PPQ |>
group_by(term, exam) |>
# split into seperate data
group_split() |>
# name the data -- vec. input
setNames(
PPQ |>
distinct(term, exam) |>
arrange(term, exam) |>
# paste distinct strings for naming together
unite("name", term, exam) |>
# grab vector of name
pull(name)
)
?uniteunidentified : T, F Classcohorts |>
filter(term == "F23",exam=="Midterm") |>
group_by(unidentified) |>
summarize(
n = n(),
mean = round(mean(Total.Score), 2),
sd = round(sd(Total.Score), 2)
)cohorts |>
filter(term == "F23",exam=="Midterm") |>
summarize(
n = n(),
mean = round(mean(Total.Score), 2),
sd = round(sd(Total.Score), 2)
)library(patchwork)
p1 <-
cohorts |>
filter(term == "F23") |>
mutate(unidentified = factor(unidentified)) |>
ggplot(aes(x=Total.Score, color = unidentified)) +
geom_histogram(binwidth = 1)
p2 <-
cohorts |>
filter(term == "F23") |>
mutate(unidentified = factor(unidentified)) |>
ggplot(aes(x=Total.Score, color = unidentified)) +
geom_boxplot()
p1 / p2\[ H_O : \mu_{\text{identified}}-\mu_{\text{UN-identified}}=0 \\ H_A : \mu_{\text{identified}}-\mu_{\text{UN-identified}}\ne0 \]
Welch Two Sample t-test
Assumptions
# T-tst comparing 2 groups means
t.test(
Total.Score ~ unidentified,
alternative = "two.sided",
data = f23_mid)##
## Welch Two Sample t-test
##
## data: Total.Score by unidentified
## t = -0.072867, df = 469.05, p-value = 0.9419
## alternative hypothesis: true difference in means between group FALSE and group TRUE is not equal to 0
## 95 percent confidence interval:
## -0.9769727 0.9071074
## sample estimates:
## mean in group FALSE mean in group TRUE
## 27.30303 27.33796
Midterm and Final)cohorts_wide <- cohorts |>
filter(exam %in% c("Midterm", "Final")) |>
select(term, student_id, exam, pct) |>
pivot_wider(
names_from = exam,
values_from = pct
)
cohorts_wide |>
ggplot(aes(x = Midterm, y = Final)) +
geom_point(alpha = 0.5) +
geom_smooth(method = "lm", se = TRUE) +
facet_wrap(~ term) +
labs(
x = "Midterm Performance",
y = "Final Performance"
) +
theme_minimal()## `geom_smooth()` using formula = 'y ~ x'
## Warning: Removed 14 rows containing non-finite outside the scale range
## (`stat_smooth()`).
## Warning: Removed 14 rows containing missing values or values outside the scale range
## (`geom_point()`).
appears to be bi-modal behavior
underlying latent variable
lm_by_term <- cohorts_wide |>
drop_na(Midterm, Final) |>
group_by(term) |>
group_nest() |>
mutate(
results = map(data, ~ {
fit <- lm(Final ~ Midterm, data = .x)
list(
model = fit,
summary = summary(fit)
)
})
) |>
select(term, results) |>
deframe()##
## Call:
## lm(formula = Final ~ Midterm, data = .x)
##
## Coefficients:
## (Intercept) Midterm
## 0.1848 0.8196
##
## Call:
## lm(formula = Final ~ Midterm, data = .x)
##
## Coefficients:
## (Intercept) Midterm
## 0.1323 0.8359
##
## Call:
## lm(formula = Final ~ Midterm, data = .x)
##
## Coefficients:
## (Intercept) Midterm
## 0.01273 0.95441
cohorts |>
group_by(term, student_id) |>
arrange(term, student_id, factor(exam, levels = c("Midterm", "Final")))## Warning: package 'lme4' was built under R version 4.4.3
## Loading required package: Matrix
##
## Attaching package: 'Matrix'
## The following objects are masked from 'package:tidyr':
##
## expand, pack, unpack
mixed_model <- cohorts |>
mutate(
exam = factor(exam, levels = c("Midterm", "Final")),
term = factor(term)
) |>
lmer(
pct ~ exam * term + (1 | term:student_id),
data = _
)## Linear mixed model fit by REML ['lmerMod']
## Formula: pct ~ exam * term + (1 | term:student_id)
## Data: mutate(cohorts, exam = factor(exam, levels = c("Midterm", "Final")),
## term = factor(term))
## REML criterion at convergence: -1723.063
## Random effects:
## Groups Name Std.Dev.
## term:student_id (Intercept) 0.14429
## Residual 0.08039
## Number of obs: 1474, groups: term:student_id, 744
## Fixed Effects:
## (Intercept) examFinal termS24 termW24
## 0.80285 0.04009 -0.02848 -0.03671
## examFinal:termS24 examFinal:termW24
## -0.06213 -0.03325
## Linear mixed model fit by REML ['lmerMod']
## Formula: pct ~ exam * term + (1 | term:student_id)
## Data: mutate(cohorts, exam = factor(exam, levels = c("Midterm", "Final")),
## term = factor(term))
##
## REML criterion at convergence: -1723.1
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -2.99108 -0.39591 0.09085 0.45928 2.32793
##
## Random effects:
## Groups Name Variance Std.Dev.
## term:student_id (Intercept) 0.020819 0.14429
## Residual 0.006463 0.08039
## Number of obs: 1474, groups: term:student_id, 744
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 0.802854 0.009575 83.850
## examFinal 0.040092 0.006635 6.042
## termS24 -0.028475 0.016576 -1.718
## termW24 -0.036707 0.013548 -2.710
## examFinal:termS24 -0.062125 0.011504 -5.400
## examFinal:termW24 -0.033250 0.009399 -3.538
##
## Correlation of Fixed Effects:
## (Intr) exmFnl trmS24 trmW24 eF:S24
## examFinal -0.343
## termS24 -0.578 0.198
## termW24 -0.707 0.243 0.408
## exmFnl:tS24 0.198 -0.577 -0.342 -0.140
## exmFnl:tW24 0.242 -0.706 -0.140 -0.342 0.407
## Warning: package 'performance' was built under R version 4.4.3
Null Model :
null_model <- cohorts |>
mutate(
term = factor(term)
) |>
lmer(
pct ~ 1 + (1 | term:student_id),
data = _
)
performance::icc(null_model)##
## Attaching package: 'psych'
## The following object is masked from 'package:effectsize':
##
## phi
## The following objects are masked from 'package:ggplot2':
##
## %+%, alpha
scree_data <- cohorts |>
group_by(term, exam) |>
group_modify(~ {
items <- .x |>
select(starts_with("Q")) |>
# Remove items that were not administered for this exam
select(where(~ !all(is.na(.x)))) |>
# Remove items with no variation
select(where(~ n_distinct(.x, na.rm = TRUE) > 1))
R <- psych::tetrachoric(items)$rho
eig <- eigen(R)$values
tibble(
component = seq_along(eig),
eigenvalue = eig
)
}) |>
ungroup()## Warning in cor.smooth(mat): Matrix was not positive definite, smoothing was
## done
## Warning in cor.smooth(mat): Matrix was not positive definite, smoothing was
## done
## Warning in cor.smooth(mat): Matrix was not positive definite, smoothing was
## done
## Warning in cor.smooth(mat): Matrix was not positive definite, smoothing was
## done
## Warning in cor.smooth(mat): Matrix was not positive definite, smoothing was
## done
## Warning in cor.smooth(mat): Matrix was not positive definite, smoothing was
## done
scree_data |>
ggplot(aes(x = component, y = eigenvalue)) +
geom_point() +
geom_line() +
geom_hline(yintercept = 1, linetype = "dashed") +
facet_grid(term ~ exam, scales = "free_x") +
labs(
x = "Component",
y = "Eigenvalue",
title = "Scree plots by term and exam"
)Analysis Suggestion : UCLA Advanced Research Comp. : Stats