0

I've ran a single-factor ANOVA on my data set and followed that with a TukeyHSD post-hoc test. I then used multcompLetters() to assign letters to the significant TukeyHSD results. I'm now trying to add the letters to an interaction plot. However, I can't seem to figure out a way to do this and have looked at several examples using boxplots but I am still lost. Any help or suggestions is greatly appreciated.

Here is the code I have used so far;

Below is a sample of data from the code I used - I am looking at whether poker player skill and/or the quality of the poker hand impact the amount of earnings in a poker game.

head(poker)

    Skill   Hand    Limit  Earnings
    <chr>  <chr>    <chr>  <dbl>
1   Expert  Bad     Fixed   4.00
2   Average Bad     Fixed   5.55
3   Expert  Good    Fixed   9.45
4   Average Good    Fixed   7.19
5   Expert  Neutral Fixed   5.71
6   Average Neutral Fixed   5.32

# read in the csv file
poker <- read.csv("poker_skill.csv", header=T)

# create a model including an interaction
mod1 = lm(Earnings~Hand + Skill + Hand:Skill, data = poker)
Anova(mod1, type = "3")

# Performa Tukey's HSD test on mod1
TukeyHSD(aov(mod1))

# Use the multcompLetters4() function in the multcompView package to assign letters to 
the significant results
Letters <- multcompLetters4(mod1, TukeyHSD(aov(mod1)), reversed = TRUE)
Letters

# Create an interaction plot and then add the Letters to the plot
pokerInt <- poker %>%
  group_by(Hand,Skill) %>%
  summarise(mean=mean(Earnings)
        
ggplot(poker, aes(x=factor(Hand), y=Earnings, colour=Skill)) +
  geom_point(data=pokerInt, aes(y=mean)) +
  geom_line(data=pokerInt, aes(y=mean, group=Skill)) +
  labs(x="Poker Hand", y="Poker Earnings") +
  theme_bw()

enter image description here

I am unsure on how I can add the Letters to the above interaction plot

  • The use of `geom_text()` may work for you. You can see an example here https://stackoverflow.com/questions/75761561/need-to-display-geom-col-labels-above-bar-as-n-a-when-they-are-0/75761679#75761679 with a column plot and built in data. You can adapt the `labeldata` object for your specific needs. Note that you can, and likely should in your case create a separate dataframe for the labels rather than using labels from the same one as used for plotting as here https://stackoverflow.com/questions/75769002/how-can-i-add-number-of-non-0-observations-of-each-group-in-ggplot/75771519#75771519 – dandrews Mar 22 '23 at 21:47
  • Hey, I think this answer may help: https://stackoverflow.com/questions/70854552/any-other-options-besides-the-traditional-cld-bar-graph/70863531#70863531 – Paul Schmidt Mar 23 '23 at 12:05

1 Answers1

1

You can add compact letters to your ggplot function using geom_text(). To do this you need some manipulation of the output from multcompLetters4() and later you could join the resulting compact letter output to your summary data containing means and letters (pokerInt). To show how to do this, I just created a random sample based on your data and adding few more rows. The example data (poker) used to produce here can be found below.

Create a model including an interaction

library(tidyverse)

mod1 = lm(Earnings~Hand + Skill + Hand:Skill, data = poker)
summary(mod1)

car::Anova(mod1, type = "3")

Use the multcompLetters4() function in the multcompView package to assign letters to

library(multcomp);library(multcompView)
Letters <- multcompLetters4(mod1, TukeyHSD(aov(mod1)), 
reversed = TRUE)

Provide summary data including means of groups

pokerInt <- poker %>%
  group_by(Hand,Skill) %>%
  summarise(mean=mean(Earnings))

Adding the compact letter display to the table

tukey.cld <- as.data.frame.list(Letters$`Hand:Skill`)

Adding interaction levels to corresponding letters to join with summary data

tukey.cld$Levels <- rownames(tukey.cld) ; rownames(tukey.cld) <- NULL

tukey.cld <- select(tukey.cld,Levels,Letters)
tukey.cld <- separate(tukey.cld, col = "Levels", into = 
c("Hand","Skill"), sep = ":",remove = T)

Join letters with summary data (pokerInt) for plotting

pokerInt <- left_join(pokerInt, tukey.cld, by=c("Hand", "Skill"))

Here the pokerInt contains both means and letters and can be passed to ggplot function

pokerInt

  Hand    Skill   mean Letters
  Bad     Average  6.28    abc    
  Bad     Expert   3.5     a      
  Good    Average  8.04    bc     
  Good    Expert   9.07    c      
  Neutral Average  5.41    ab     
  Neutral Expert   6.10    abc    

Now we could add the compact letters to plot using geom_text(). You can play with vjust and hjust to adjust the position of letters

ggplot(poker, aes(x=factor(Hand), y=Earnings, colour=Skill)) +
          geom_point(data=pokerInt, aes(y=mean)) +
          geom_line(data=pokerInt, aes(y=mean, group=Skill)) +
          geom_text(data=pokerInt
                    , aes(y=mean, label=Letters)
                    , position = position_dodge(0.90), size = 3.5, 
                    , vjust= 0.0, hjust= -0.3
                    , colour = "gray25"
                    , fontface = "bold")+
          labs(x="Poker Hand", y="Poker Earnings") +
          theme_bw()

And finally the plot with the compact letters: enter image description here

The example data

poker <- read.table(text = "Skill   Hand    Limit   Earnings
Expert  Bad Fixed   4
Average Bad Fixed   5.55
Expert  Good    Fixed   9.45
Average Good    Fixed   7.19
Expert  Neutral Fixed   5.71
Average Neutral Fixed   5.32
Expert  Bad Fixed   3
Average Bad Fixed   7
Expert  Good    Fixed   8.7
Average Good    Fixed   8.9
Expert  Neutral Fixed   6.5
Average Neutral Fixed   5.5
",header=T)
S-SHAAF
  • 1,863
  • 2
  • 5
  • 14