Files
osk.rs/doc/report.Rnw
2026-02-05 18:01:51 +01:00

282 lines
7.7 KiB
Plaintext

\documentclass[conference,a4paper]{IEEEtran}
\usepackage{graphicx} % for including figures
\usepackage{booktabs} % for nicer tables
\begin{document}
\section{Abstract}\label{abstract}
We evaluated three on-screen keyboard layouts: QWERTY, Dvorak, and Circle. Objective performance, measured in words per minute (WPM), showed a significant main effect of layout. Post-hoc comparisons revealed that QWERTY was significantly faster than both Dvorak and Circle, while no difference was observed between Dvorak and Circle. Total error rate (TER) did not differ significantly between layouts. Subjective workload ratings assessed via NASA-TLX were similar for Dvorak and Circle, but QWERTY was perceived as less demanding. These results indicate that QWERTY offers superior typing speed, whereas error rates and perceived workload are comparable across layouts.
\section{Introduction}\label{introduction}
\section{Keyboard Designs}\label{keyboard-designs}
Three on-screen keyboard layouts were evaluated in this study: QWERTY, Dvorak, and a custom-designed Circle layout.
1. QWERTY: The standard layout commonly used in English typing, serving as a baseline for comparison.
2. Dvorak: An alternative layout designed to increase typing efficiency by placing frequently used letters in more accessible positions.
3. Circle Layout: A custom layout developed for this study, in which keys were arranged in a circular pattern. Letters that occur more frequently in English were positioned closer to the center and rendered larger to facilitate faster access. Less frequently used letters were placed toward the periphery and sized smaller, aiming to optimize ergonomic reach and visual salience.
This design allowed us to investigate both established and novel layouts, comparing objective typing performance, error rates, and subjective workload.
\begin{figure}[h]
\centering
\includegraphics[width=0.5\textwidth]{images/qwerty-pic.png}
\caption{QWERTY Keyboard Layout}
\label{fig:qwerty}
\end{figure}
\begin{figure}[h]
\centering
\includegraphics[width=0.6\textwidth]{images/dvorak-pic.png}
\caption{Dvorak Keyboard Layout}
\label{fig:dvorak}
\end{figure}
\begin{figure}[h]
\centering
\includegraphics[width=0.4\textwidth]{images/circle-pic.png}
\caption{Circle Keyboard Layout}
\label{fig:circle}
\end{figure}
\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}
<<echo=FALSE>>=
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
<<results='asis', echo=FALSE>>=
kable(ter, format="latex", booktabs=TRUE)
@
\caption{Summary of Total Error Rate (TER)}
\end{table}
% WPM table
\begin{table}[h]
\centering
\scriptsize
<<results='asis', echo=FALSE>>=
kable(wpm, format="latex", booktabs=TRUE)
@
\caption{Summary of Words per Minute (WPM)}
\end{table}
<<echo=FALSE>>=
# 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}
<<echo=FALSE>>=
# 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
<<echo=FALSE>>=
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
<<echo=FALSE>>=
# --- 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
<<echo=FALSE>>=
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}