Visualizing Item Analysis: Creating Interactive Plots for Educational Assessments

R Psychometric

In this post, I demonstrate how to create interactive item analysis plots for educational assessments using R packages.

(5 min read)

Tarid Wongvorachan (University of Alberta)https://www.ualberta.ca
2025-01-12

Introduction

Show code
datatable(df, options = list(pageLength = 10))
Show code
# Subset Non-French
df_non_french <- df %>% filter(language == "Non-French")

# Subset French
df_french <- df %>% filter(language == "French")

# Subset Field Test Item
df_field_test <- df %>% filter(item_type == "field test")

# Subset Operational Item
df_operational <- df %>% filter(item_type == "operational")

All Data Points

Show code
# Define color mapping
flag_colors <- c("Good" = "green", "Caution" = "orange", "Poor" = "red")

# Create ggplot
p <- ggplot(df, aes(x = Discrimination, y = Difficulty, color = flag)) +
  geom_point(size = 1, aes(text = paste("Item:", Item,
                                        "<br>N:", N,
                                        "<br>Language:", language,
                                        "<br>Item Type:", item_type))) +
  geom_vline(xintercept = 0.20, linetype = "dashed", color = "blue") +
  geom_hline(yintercept = 0.50, linetype = "dashed", color = "blue") + 
  scale_color_manual(values = flag_colors) +
  labs(title = "Difficulty vs. Discrimination (all)",
       x = "Discrimination",
       y = "Difficulty") +
  theme_minimal()

# Convert ggplot to plotly
ggplotly(p)

Language

Non-French

Show code
# Create ggplot
p <- ggplot(df_non_french, aes(x = Discrimination, y = Difficulty, color = flag)) +
  geom_point(size = 1, aes(text = paste("Item:", Item,
                                        "<br>N:", N,
                                        "<br>Language:", language,
                                        "<br>Item Type:", item_type))) +
  geom_vline(xintercept = 0.20, linetype = "dashed", color = "blue") +
  geom_hline(yintercept = 0.50, linetype = "dashed", color = "blue") + 
  scale_color_manual(values = flag_colors) +
  labs(title = "Difficulty vs. Discrimination (Non-French)",
       x = "Discrimination",
       y = "Difficulty") +
  theme_minimal()

# Convert ggplot to plotly
ggplotly(p)

French

Show code
# Create ggplot
p <- ggplot(df_french, aes(x = Discrimination, y = Difficulty, color = flag)) +
  geom_point(size = 1, aes(text = paste("Item:", Item,
                                        "<br>N:", N,
                                        "<br>Language:", language,
                                        "<br>Item Type:", item_type))) +
  geom_vline(xintercept = 0.20, linetype = "dashed", color = "blue") +
  geom_hline(yintercept = 0.50, linetype = "dashed", color = "blue") + 
  scale_color_manual(values = flag_colors) +
  labs(title = "Difficulty vs. Discrimination (French)",
       x = "Discrimination",
       y = "Difficulty") +
  theme_minimal()

# Convert ggplot to plotly
ggplotly(p)

Item Type

Field Test Item

Show code
# Create ggplot
p <- ggplot(df_field_test, aes(x = Discrimination, y = Difficulty, color = flag)) +
  geom_point(size = 1, aes(text = paste("Item:", Item,
                                        "<br>N:", N,
                                        "<br>Language:", language,
                                        "<br>Item Type:", item_type))) +
  geom_vline(xintercept = 0.20, linetype = "dashed", color = "blue") +
  geom_hline(yintercept = 0.50, linetype = "dashed", color = "blue") + 
  scale_color_manual(values = flag_colors) +
  labs(title = "Difficulty vs. Discrimination (Field Test)",
       x = "Discrimination",
       y = "Difficulty") +
  theme_minimal()

# Convert ggplot to plotly
ggplotly(p)

Operational Item

Show code
# Create ggplot
p <- ggplot(df_operational, aes(x = Discrimination, y = Difficulty, color = flag)) +
  geom_point(size = 1, aes(text = paste("Item:", Item,
                                        "<br>N:", N,
                                        "<br>Language:", language,
                                        "<br>Item Type:", item_type))) +
  geom_vline(xintercept = 0.20, linetype = "dashed", color = "blue") +
  geom_hline(yintercept = 0.50, linetype = "dashed", color = "blue") + 
  scale_color_manual(values = flag_colors) +
  labs(title = "Difficulty vs. Discrimination (Operational Item)",
       x = "Discrimination",
       y = "Difficulty") +
  theme_minimal()

# Convert ggplot to plotly
ggplotly(p)

Concluding remark

Reuse

Text and figures are licensed under Creative Commons Attribution CC BY 4.0. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".

Citation

For attribution, please cite this work as

Wongvorachan (2025, Jan. 12). Tarid Wongvorachan: Visualizing Item Analysis: Creating Interactive Plots for Educational Assessments. Retrieved from https://taridwong.github.io/posts/2025-01-12-cttplotly/

BibTeX citation

@misc{wongvorachan2025visualizing,
  author = {Wongvorachan, Tarid},
  title = {Tarid Wongvorachan: Visualizing Item Analysis: Creating Interactive Plots for Educational Assessments},
  url = {https://taridwong.github.io/posts/2025-01-12-cttplotly/},
  year = {2025}
}