Plotting individual means (and CI) for each participant and condition

Imagine that we have an experiment in which participants do two different tasks (type a and b) and are assigned to two different conditions (A and B). So we want to know how fast they are in each type of stimuli and task. As we have few participants we can explore individual estimates. Below are listed some things that we want to handle on our visualization.

  • Differences in type of stimuli for each participant (with each type )
  • Differences on variability for each condition (a column for each condition)

To do that we are going to calculate with Rmisc the individual means and confidence intervals for each participant in each type of task. Then we will order all participants by their mean response time (with “reorder(part, -mean_rt)”). Doing that, we can set a narrative in the data in which readers will notice that reaction times in condition A and B show different patterns: condition B show more exterme values (higher and lower than A).

Available as gist here.

</pre>
if (!require("pacman")) install.packages("pacman")
pacman::p_load("ggplot2", "Rmisc")
#############################################################
# Preparing data (you can skip this and go to the plot : )
#############################################################
# Simulate some date by trial
parts = 30 # Our participants
trials = 60 # Our Trials
df=data.frame()

# Simulate some date by trial
parts = 30 # Our participants
trials = 60 # Our Trials
conds = 2 # How many conditions we have
df=data.frame()
for(i in 1:30 ){
# As I'm not focusing on simulatng realistic data, the responses are totally trivial
mean = rnorm(1, 0.5, 1)
response1 = rnorm(trials/2, mean = mean, sd = sd)
response2 = rnorm(trials/2, mean = mean - runif(1, 0.1, 0.4), sd = sd)
response <- c(response1, response2)
type = c(rep("a", 30), rep("b", 30))
cond = "A"
df2 = data.frame( part = rep(i, 60), cond = rep(cond, 60), type = type, RT = response)
df=rbind(df, df2)
}
for(i in 30:60 ){
mean = rnorm(1, 0.5, 3)
sd = runif(1, 2, 5)
response1 = rnorm(trials/2, mean = mean, sd = sd)
response2 = rnorm(trials/2, mean = mean - runif(1, 0.5, 4), sd = sd)
response <- c(response1, response2)
type = c(rep("a", 30), rep("b", 30))
cond = "B"
df2 = data.frame( part = rep(i, 60), cond = rep(cond, 60), type = type, RT = response)
df=rbind(df, df2)
}

#############################################################
# Prepare the data
#############################################################

tab = summarySEwithin(data = df, measurevar = "RT",
withinvars = c("type", "part"), betweenvars = "cond")
# Get the mean of each participant in both types.
# this is just for ordering the data
tab = tab %>% group_by(part) %>%
summarise(mean_rt = mean(RT)) %>%
left_join(tab, . )
# Ordering by mean RT
tab = arrange(tab, desc(mean_rt), part)
#############################################################
# Do the plot
#############################################################
pd <- position_dodge(0.4)
# Change them values to do a clean one
theme_set(theme_bw())
my_theme <- theme(panel.grid.major.x = element_blank(),
panel.grid.minor.x= element_blank(),
panel.background = element_blank(),
panel.border = element_blank(),
strip.text.x = element_text(size=14), strip.text.y = element_text(size=16),
strip.background = element_rect(colour="black"),
axis.text.x = element_text(color="black", size=14),
axis.text.y = element_text(color="black", size=14),
axis.title.x = element_text(face="bold", size=18),
axis.title.y = element_text(face="bold",size=18),
axis.ticks = element_blank(),
legend.title = element_text(size=14), legend.text = element_text(size = 14),
plot.title = element_text(vjust = 1.3, face="bold", size=20),
plot.margin = unit(c(1.5, 1.5, 1.5, 1.5), "cm")
)

ggplot(tab, aes(x = reorder(part, -mean_rt), y = RT, group = type, col = type)) +
geom_point(position=pd) +
coord_flip() + facet_wrap(~cond) +
ylab("RT") + xlab("Participant") + ggtitle("Reaction times") +
geom_linerange(aes(ymin= RT-se, ymax= RT+se), size = 1, position = pd) +
my_theme +
theme(axis.text.y = element_blank(),
legend.position = c(.9,.8))
<pre>

Our result:

 

As you can see, our task B seems to have more variability and also we can see how the type of task has less overlapping in each participant.