0

In R, I'm plotting data from two different dataframes, called respectively ASD and TD, using ggplot boxplot.

Each dataframe reports 3 variables:

  • a (numeric)
  • b (numeric)
  • condition (categorial, can be "ASD" or "TD")

enter image description here enter image description here

I successfully created two graph; in each graph I plotted the same variable, respectively a and b, from the two datafames, side by side, so to compare them. I then added to each graph a given string, namely "Jonh" and "Jerry". Both strings are printed at y=35, using annotate.

problem: how can I change the y position for each string? In the example, I would like to print the string "Jerry" (in the graph for variable b) at y=10

enter image description here

Here follows the code I used:

#clearing variable and console
cat("\014")
rm(list = ls())
message("Graphic test for boxplot")

#libraries
library(ggplot2)
library(reshape2)

# creation of dataframe ASD, with numeric variables 'a' and 'b',
# and a categorial variable 'condition' with fixed value 'ASD' 
a <- c(1:10)
b <- c(26:35)
ASD <- cbind(a,b)
ASD.df <-as.data.frame(ASD)
ASD.df$condition <- "ASD"

# creation of dataframe TD, with numeric variables 'a' and 'b',
# and a categorial variable 'condition' with fixed value 'TD' 
a <- c(6:15)
b <- c(24:33)
TD <- cbind(a,b)
TD.df <-as.data.frame(TD)
TD.df$condition <- "TD"


# union of ASD and TD in a single dataframe C
C.df <- rbind(ASD.df,TD.df)

# reshaping of C for ggplot, using variable 'condition'
C.df_melted <- melt(C.df, id.var = "condition")


#strings I want to visualise on each graph
myStr <- c("John", "Jerry")

#do I want a fixed y lim?
FIXED_Y_LIM <- TRUE

myBox <- ggplot(data=C.df_melted, aes(x=condition, y=value, fill=variable))+
geom_boxplot(show.legend = FALSE) +
facet_wrap(~variable, scale="free") + 
annotate(geom="text", x=1.5, y=35, label= myStr)

# it forces y scale in this range
if(FIXED_Y_LIM==TRUE)
{
  myBox <- myBox + ylim(0, 40)  
}

myBox

I tried to solve modyfing the annotate line from

annotate(geom="text", x=1.5, y=35, label= myStr)

to

annotate(geom="text", x=1.5, y=c(35, 10), label= myStr)

but I obtain this error that I don't understand:

Error: Aesthetics must be either length 1 or the same as the data (4): label

Thanks for suggestions.

valerio_sperati
  • 793
  • 2
  • 9
  • 23
  • `myStr` is not in `C.df_melted`, hence the error. Also, possible duplicate of https://stackoverflow.com/questions/11889625/annotating-text-on-individual-facet-in-ggplot2 – warnbergg Jul 04 '19 at 13:40

2 Answers2

1

Using Annotating text on individual facet in ggplot2, we add the positions and each label to C.df_melted. Instead of annotate we use geom_text:

C.df_melted$x <- rep(1.5, nrow(C.df_melted))
C.df_melted$y <- c(rep(35, nrow(C.df_melted)/2), rep(10, nrow(C.df_melted)/2))
C.df_melted$myStr <- c(rep("John", nrow(C.df_melted)/2), rep("Jerry", nrow(C.df_melted)/2))

myBox <- ggplot(data=C.df_melted, aes(x=condition, y=value, fill=variable))+
geom_boxplot(show.legend = FALSE) +
facet_wrap(~variable, scale="free") + 
geom_text(mapping = aes(x = x, y = y, label = myStr))
warnbergg
  • 552
  • 4
  • 14
1

It's referring to the number of vectors in the C.df_melted data.frame.

An alternative is to use labeller on facet_wrap():

ggplot(data=C.df_melted, aes(x=condition, y=value, fill=variable)) +
geom_boxplot(show.legend = FALSE) +
facet_wrap(~variable, scale="free", labeller=as_labeller(setNames(myStr, c("a", "b"))))

Or to answer your question more directly with the aid of Annotating text on individual facet in ggplot2 and geom_text():

ggplot(data=C.df_melted, aes(x=condition, y=value, fill=variable)) +
geom_boxplot(show.legend = FALSE) +
facet_wrap(~variable, scale="free") +
geom_text(data=data.frame(label=myStr, y=c(35, 10), variable=c("a", "b")), mapping=aes(x=1.5, y=y, label=label))
KevinJWalters
  • 193
  • 1
  • 7