\documentclass[conference,a4paper]{IEEEtran} \usepackage{graphicx} % for including figures \usepackage{booktabs} % for nicer tables \begin{document} \section{Abstract}\label{abstract} \section{Introduction}\label{introduction} \section{Keyboard Designs}\label{keyboard-designs} \section{Experiment}\label{experiment} \subsection{Participants}\label{participants} \subsection{Apparatus}\label{apparatus} \subsection{Procedure}\label{procedure} \section{Results}\label{results} \subsection{Descriptive Statistics}\label{descriptive-statistics} \subsubsection{Objective Measures}\label{objective-measures} <>= library(knitr) # Read the results CSV results <- read.csv("../data/results.csv", sep=",", header=TRUE) # Summarize TER and WPM ter <- summary(results[, c("qwerty_ter", "dvorak_ter", "circle_ter")]) wpm <- summary(results[, c("qwerty_wpm", "dvorak_wpm", "circle_wpm")]) @ % TER table \begin{table}[h] \centering \scriptsize <>= kable(ter, format="latex", booktabs=TRUE) @ \caption{Summary of Total Error Rate (TER)} \end{table} % WPM table \begin{table}[h] \centering \scriptsize <>= kable(wpm, format="latex", booktabs=TRUE) @ \caption{Summary of Words per Minute (WPM)} \end{table} <>= # Create figures directory if it doesn't exist dir.create("../figures", showWarnings=FALSE) # Helper functions for standard deviation and confidence intervals mean_sd <- function(x) { m <- mean(x) s <- sd(x) c(mean=m, lower=m-s, upper=m+s) } mean_ci <- function(x) { m <- mean(x) se <- sd(x)/sqrt(length(x)) ci <- qt(0.975, df=length(x)-1)*se c(mean=m, lower=m-ci, upper=m+ci) } # TER stats ter_stats <- rbind( mean_ci(results$qwerty_ter), mean_ci(results$dvorak_ter), mean_ci(results$circle_ter) ) # Save TER barplot as PDF using LaTeX-compatible fonts pdf("../figures/ter_plot.pdf") bar_pos <- barplot( ter_stats[,"mean"], names.arg=c("QWERTY","DVORAK","CIRCLE"), ylab="Total Error Rate (TER)", main="TER of layouts", ylim=c(0, max(ter_stats[,"upper"])*1.1) ) # Add confidence intervals arrows( x0=bar_pos, y0=ter_stats[,"lower"], x1=bar_pos, y1=ter_stats[,"upper"], angle=90, code=3, length=0.05 ) dev.off() # WPM stats wpm_stats <- rbind( mean_sd(results$qwerty_wpm), mean_sd(results$dvorak_wpm), mean_sd(results$circle_wpm) ) # Save WPM barplot as PDF using LaTeX-compatible fonts pdf("../figures/wpm_plot.pdf") bar_pos <- barplot( wpm_stats[,"mean"], names.arg=c("QWERTY","DVORAK","CIRCLE"), ylab="Words per minute (WPM)", main="WPM of layouts", ylim=c(0, max(wpm_stats[,"upper"])*1.1) ) arrows( x0=bar_pos, y0=wpm_stats[,"lower"], x1=bar_pos, y1=wpm_stats[,"upper"], angle=90, code=3, length=0.05 ) dev.off() @ % Include TER plot \begin{figure}[h] \centering \includegraphics[width=\columnwidth]{../figures/ter_plot.pdf} \caption{Total Error Rate (TER) by Keyboard Layout} \end{figure} % Include WPM plot \begin{figure}[h] \centering \includegraphics[width=\columnwidth]{../figures/wpm_plot.pdf} \caption{Words per Minute (WPM) by Keyboard Layout} \end{figure} \subsubsection{Subjective Measures}\label{subjective-measures} <>= # Read NASA-TLX data nasa <- read.csv("../data/nasaTLX.csv") nasa$layout <- factor(nasa$layout) # Save boxplots as PDF using LaTeX-compatible fonts pdf("../figures/nasa_boxplots.pdf") par(mfrow=c(2,3)) # Arrange plots in 2 rows x 3 columns boxplot(mental_demand ~ layout, data=nasa, main="Mental Demand") boxplot(physical_demand ~ layout, data=nasa, main="Physical Demand") boxplot(performance ~ layout, data=nasa, main="Performance") boxplot(effort ~ layout, data=nasa, main="Effort") boxplot(frustration ~ layout, data=nasa, main="Frustration") par(mfrow=c(1,1)) dev.off() @ % Include NASA-TLX boxplots \begin{figure}[h] \centering \includegraphics[width=\columnwidth]{../figures/nasa_boxplots.pdf} \caption{NASA-TLX Scores by Keyboard Layout} \end{figure} \subsection{Inferential Statistics}\label{inferential-statistics} Independent var: - QWERTY - DVORAK - Circle Dependent var: - WPM - TER - Nasa-TLX %Anova RM for WPM <>= library(tidyr) library(dplyr) # Add participant ID results$id <- 1:nrow(results) # --- WPM Long Format --- wpm_long <- results %>% select(id, qwerty_wpm, dvorak_wpm, circle_wpm) %>% pivot_longer( cols = -id, names_to = "layout", values_to = "wpm" ) wpm_long$id <- factor(wpm_long$id) wpm_long$layout <- factor(wpm_long$layout, levels=c("qwerty_wpm","dvorak_wpm","circle_wpm"), labels=c("QWERTY","DVORAK","CIRCLE")) # --- RM ANOVA for WPM --- anova_wpm <- aov(wpm ~ layout + Error(id/layout), data=wpm_long) # Print ANOVA table summary(anova_wpm) @ %Anova RM for TER <>= # --- TER Long Format --- ter_long <- results %>% select(id, qwerty_ter, dvorak_ter, circle_ter) %>% pivot_longer( cols = -id, names_to = "layout", values_to = "ter" ) ter_long$id <- factor(ter_long$id) ter_long$layout <- factor(ter_long$layout, levels=c("qwerty_ter","dvorak_ter","circle_ter"), labels=c("QWERTY","DVORAK","CIRCLE")) # --- RM ANOVA for TER --- anova_ter <- aov(ter ~ layout + Error(id/layout), data=ter_long) summary(anova_ter) @ % Post-Hoc analysis with bonferroni correction for WPM <>= suppressMessages(library(emmeans)) suppressMessages(emm_wpm <- emmeans(anova_wpm, ~ layout)) posthoc <- pairs(emm_wpm, adjust = "bonferroni") print(posthoc) @ \subsubsection{Objective Measures}\label{objective-measures-1} \subsubsection{Subjective Measures}\label{subjective-measures-1} \section{Discussion}\label{discussion} \end{document}