Use Visualizations to answer the following questions: Inter-goniometer: do the two goniometers agree? Intra-goniometer: do the goniometers measure consistently the knee joint angle across the three repeated measurements?
Data set:
The Challenge:
Visualize the data to answer the following questions:
Reference:
Eliasziw M, Young SL, Woodbury MG, Fryday-Field K. Statistical methodology for the concurrent assessment of interrater and intrarater reliability: using goniometric measurements as an example. Phys Ther. 1994 Aug;74(8):777-88. doi: 10.1093/ptj/74.8.777. PMID: 8047565.
A description of the challenge can also be found here.
A recording of the session can be found here.
high resolution image
high resolution image
The html file can be found here.
The html file can be found here.
The html file can be found here.
The html file can be found here.
The html file can be found here.
The SAS file can be found here.
The Python file can be found here.
library(readxl)
library(dplyr)
library(tidyr)
library(ggplot2)
# Load data
d <- read_excel('Data/2024-12-11-psi-vissig-goniometer.xlsx') |>
mutate(time=as.numeric(time))
# Bland-Altman plot - Inter-goniometer agreement
df<-d |>
pivot_wider(names_from = `rater`, values_from = `y`) |>
mutate(
time = paste("T", time),
diff = manual - electro,
avg = (manual + electro) / 2)
df2 <- df |>
group_by(time) |>
summarise(
g_avg = mean(avg),
g_diff = mean(diff),
sd_diff = sd(diff),
n = n()
)
df2
df <- df |>
left_join(df2)
ggplot(data=df, aes(x = avg, y = diff, col = ifelse(diff>(g_diff+1.96*sd_diff) | diff<(g_diff-1.96*sd_diff), "1", "0"))) +
geom_point() +
geom_rug(col="grey") +
# orange and blue colors do not show legend
scale_color_manual(values = c("black", "red")) +
geom_hline(aes(yintercept = g_diff)) +
geom_hline(aes(yintercept = g_diff+1.96*sd_diff), linetype = "dashed") +
geom_hline(aes(yintercept = g_diff-1.96*sd_diff), linetype = "dashed") +
#geom_smooth(method = "lm", se = F) +
labs(
title = "Bland-Altman plot - Inter-goniometer agreement (electro vs. manual)",
x = "Average",
y = "Difference",
caption = "Solid line represents average of differences. \nDashed lines represent limits of agreement (±1.96xSD). \nData outside 95% limits of agreement are labeled"
) +
facet_wrap(time~.) +
#plot data outside g_diff+1.96*sd_diff
geom_text(data=df, aes(label = ifelse(diff>(g_diff+1.96*sd_diff) | diff<(g_diff-1.96*sd_diff), id, NA), hjust = -0.5)) +
scale_y_continuous(limits = c(-10, 10)) +
theme_bw() +
theme(legend.position = "none")
# save the plot
ggsave("Figures/inter-goniometer-agreement.png", width = 10, height = 5)
# Bland-Altman plot - Intra-goniometer agreement
df<-NULL
for (i in 1:3){
c <- combn(1:3,2)[,i]
d1 <- d |>
filter(time %in% c) |>
pivot_wider(names_from = `time`, values_from = `y`)
names(d1) <- c("id", "goniometer", "A", "B")
d2 <- d1 |>
mutate(
diff = A - B,
avg = (A + B) / 2,
comparison=paste("T",c[1],"vs", "T", c[2]))
df <- rbind(df, d2)
}
df2 <- df |>
group_by(goniometer, comparison) |>
summarise(
g_avg = mean(avg),
g_diff = mean(diff),
sd_diff = sd(diff),
n = n()
)
df <- df |>
left_join(df2)
ggplot(data=df, aes(x = avg, y = diff, col = ifelse(diff>(g_diff+1.96*sd_diff) | diff<(g_diff-1.96*sd_diff), "1", "0"))) +
geom_point() +
geom_rug(col="grey") +
# orange and blue colors do not show legend
scale_color_manual(values = c("black", "red")) +
geom_hline(aes(yintercept = g_diff)) +
geom_hline(aes(yintercept = g_diff+1.96*sd_diff), linetype = "dashed") +
geom_hline(aes(yintercept = g_diff-1.96*sd_diff), linetype = "dashed") +
#geom_smooth(method = "lm", se = F) +
labs(
title = "Bland-Altman plot - Intra-goniometer agreement",
x = "Average",
y = "Difference",
caption = "Solid line represents average of differences. \nDashed lines represent limits of agreement (±1.96xSD). \nData outside 95% limits of agreement are labeled"
) +
# add text to geom_hline
facet_wrap(goniometer~comparison) +
geom_text(aes(label = ifelse(diff>(g_diff+1.96*sd_diff) | diff<(g_diff-1.96*sd_diff), id, NA), hjust = -0.5)) +
theme_bw() +
theme(legend.position = "none")
# save the plot
ggsave("Figures/intra-goniometer-agreement.png", width = 9, height = 6)
The html file can be found here.
For attribution, please cite this work as
SIG (2024, Dec. 11). VIS-SIG Blog: Wonderful Wednesdays December 2024. Retrieved from https://graphicsprinciples.github.io/posts/2024-12-20-wonderful-wednesdays-december-2024/
BibTeX citation
@misc{sig2024wonderful, author = {SIG, PSI VIS}, title = {VIS-SIG Blog: Wonderful Wednesdays December 2024}, url = {https://graphicsprinciples.github.io/posts/2024-12-20-wonderful-wednesdays-december-2024/}, year = {2024} }