1

I hope someone can help me with this.

I have this dataframe, an output of the dunnTest(), which contains the pairwise comparison and the p-values. The sample output of dunnTest() is below. What I am trying to do is to reshape the dataframe into a matrix and create a heatmap plot or a correlation plot tiles to visualize which groups are significantly different from each other. The output should look something like the image below. But instead of correlation values, the data inside the tiles are p-values from the dunnTest()

from this liknkhttps://stackoverflow.com/questions/12196756/significance-level-added-to-matrix-correlation-heatmap-using-ggplot2

The problem I am trying to accomplish is similar to the one posted in this link, However, no answer was given. I hope this time someone can answer such question.

I tried data.matrix() but it did not properly converted the data based on the "Comparison" column.

sorted <- 
    tibble::tribble(
      ~Comparison, ~Z, ~P.adj,
      "A1 - B1",    0.225445,     0.854086,
      "A1 - B2",    0.45513,     0.000235,
      "A1- B3",    0.32555,     0.221551,
       "B1 - B2",   0.44544,       0.0000552,
       "B2 - B3",    0.22511,      0.0000112)

1 Answers1

2

If I understood correctly, this might help you

Libraries

library(tidyverse)

Data

sorted <- 
  tibble::tribble(
    ~Comparison, ~Z, ~P.adj,
    "A1 - B1",    0.225445,     0.854086,
    "A1 - B2",    0.45513,     0.000235,
    "A1- B3",    0.32555,     0.221551,
    "B1 - B2",   0.44544,       0.0000552,
    "B2 - B3",    0.22511,      0.0000112)

x <- c("A1","B1","B2","B3")

Code

sorted %>% 
  #Separate variable Comparison in two columns
  separate(col = Comparison,into = c("var1","var2")) %>% 
  #Create temporary data.frame 
  {. ->> temp} %>% 
  #Stack temporary data.frame so we have both A1-B1 and B1-A1
  bind_rows(
    temp %>%
      rename(var1 = var2,var2 = var1)
  ) %>% 
  #Join with a combination of all levels to make a "complete matrix"
  full_join(
    expand_grid(var1 = x,var2 = x)
  ) %>% 
  mutate(
    #Rounding p-value
    P.adj = round(P.adj,4),
    #Creating a variable just for the text inside the tile, with a condition
    p_lbl = if_else(P.adj < 0.05,paste0(P.adj,"*"),as.character(P.adj))) %>% 
  #Using variable P.adj as colour 
  ggplot(aes(x = var1,y = var2,fill = P.adj))+
  geom_tile(col = "black")+
  #Optional pallette 
  scale_fill_viridis_c()+
  # Add p-values as text inside the tiles
  geom_text(aes(label = p_lbl), fontface = "bold",size = 5)

Plot

enter image description here

Vinícius Félix
  • 8,448
  • 6
  • 16
  • 32
  • Thank you very much for responding, I am getting an error `Error in eval_tidy(dots[[i]], data = out) : object 'x' not found` – Tyler Ruddenfort Sep 08 '21 at 13:59
  • 1
    I created an object called X, with all the levels is in the Data section of my answer – Vinícius Félix Sep 08 '21 at 14:01
  • Oh ok I see, my bad. Thank you very much. I'll try this again. – Tyler Ruddenfort Sep 08 '21 at 14:04
  • Thank you very much again. Just a question, is it possible to add the pvalues inside the tiles? even just the 2 decimal places of the "P.adj"? – Tyler Ruddenfort Sep 08 '21 at 14:14
  • 1
    Yes @TylerRuddenfort, I updated in my example, but I recommend that you change the colour of the text or the tile for a better contrast – Vinícius Félix Sep 08 '21 at 14:31
  • Sorry to add another question, but is it possible to just plot a rectangle in a tile that is <0.05? or maybe put a dot inside the box where the pvalues are significant? I am thinking of `geom_point()` but do not know the syntax to indicate only significant pvalues. – Tyler Ruddenfort Sep 09 '21 at 08:50
  • 1
    Hi @TylerRuddenfort yes it is possible, Updated with a solution – Vinícius Félix Sep 09 '21 at 11:18
  • Thank you very much for saving me! this really helped me. Just another question, is it possible to just indicate those significant pvalues inside the tiles and leave tiles that are not significant to be empty or no text inside? Apologies if this is causing you too much trouble. But you really did saved me and I could not thank you enough! – Tyler Ruddenfort Sep 09 '21 at 13:41
  • 1
    @TylerRuddenfort change this line ` if_else(P.adj < 0.05,paste0(P.adj,"*"),"")` so it will be an empty space – Vinícius Félix Sep 09 '21 at 14:24
  • Thank you very much!! This totally worked!!!! I really could not thank you enough. – Tyler Ruddenfort Sep 09 '21 at 14:28