简体   繁体   中英

Add n, mean and sd as numbers/numerics under boxplots with labels aligned under y-axis

Im aware of that thread , but the solution looks kinda long and complicated to me: Is there a quick and easy solution? To add the following vector under the y-axis?

yLabels <- c("","","n","mn","sd")

Reproducible data:

library(ggplot2)
library(magrittr)

mtcars <- mtcars

values <- rbind(tapply(mtcars$mpg,mtcars$gear,length)) %>% rbind(tapply(mtcars$mpg,mtcars$gear,mean)) %>% rbind(tapply(mtcars$mpg,mtcars$gear,sd)) %>%
  round(3)

levels <- rbind(levels(mtcars$gear%>%factor),matrix("",ncol=ncol(values)))

xlabs <- rbind(levels,values) %>% apply(.,2,function(x) {paste(x,collapse="\n")}) 
ggplot(mtcars, aes(x=factor(gear), y=mpg, fill=factor(gear))) + geom_boxplot() + scale_x_discrete(labels=xlabs)

This is what the above code processes:

缺少解释数字的标签

This is what i want: Labels under and "in line" with the y-axis. For n, mean and sd

在此处输入图片说明

Not the nicest solution but gives you maybe an idea how to solve it in a general way...

xlabs <- c('2.5'='\n\nn\nmn\nsd', 
           rbind(levels,values) %>% apply(.,2,function(x) {paste(x,collapse="\n")})) 
ggplot(mtcars, aes(x=gear, y=mpg, fill=factor(gear))) + 
  geom_boxplot() + 
  scale_x_continuous(breaks=c(2.5,3,4,5), labels=xlabs) +
  theme(axis.ticks.x=element_line(color=c('white', rep('black', length(xlabs[-1])))))

I think a trick would be to use numeric values instead of the factor and you could add a tick label close to your limits. This one can than be labeled and the tick mark is white in the and...

Pretty hacky but I guess there is potential...

EDIT

Ok, a little bit more general in case of factors:

mtcars$test <- as.factor(mtcars$gear)
xlabs <- 
  c('2.5'='\n\nn\nmn\nsd', 
    rbind(levels,values) %>% 
      apply(.,2,function(x) {paste(x,collapse="\n")})) 

ggplot(mtcars, aes(x=as.numeric(test), y=mpg, fill=factor(gear))) + 
  geom_boxplot() + 
  scale_x_continuous(breaks=c(0.5, seq(1,length(levels(mtcars$test)))), 
                     labels=xlabs) +
  theme(axis.ticks.x=element_line(color=c('white', 
                                          rep('black', length(xlabs[-1])))))

Factors can be represented as.numeric and then these are basically integers starting at 1. So you can just use this to put them on the continuous scale and add an extra break at 0 or 0.5 and add your extra label to the xlabs variable. To hide the tick mark you can just add a white tick plus the number of levels in your column used for the x axis.

With the valuable help of drmariod i came up with the following general solution:

1: the variable "xorigin" holds the x-value directly under the y-axis

2: met = metric-Variable , cat = categorial-Variable

library(ggplot2)
library(magrittr)

## Change only right sides to your needs ##
ds      <- diamonds
catName <- "cut"
metName <- "price"
###########################################

names(ds)[match(catName,names(ds))] <- "catVar"
names(ds)[match(metName,names(ds))] <- "metVar"

values <- rbind(tapply(ds$metVar,ds$catVar,length)) %>% rbind(tapply(ds$metVar,ds$catVar,mean)) %>% rbind(tapply(ds$metVar,ds$catVar,sd)) %>%
          round(3)
if (!is.factor(ds$catVar)) {
  ds$catVar <- factor(ds$catVar, levels=colnames(values))
}

levels <- rbind(levels(ds$catVar),matrix("",ncol=ncol(values)))

xlabs <- 
  c('2.5'='\n\nn\nmn\nsd', 
    rbind(levels,values) %>% 
      apply(.,2,function(x) {paste(x,collapse="\n")})) 

p <- ggplot(ds, aes(x=as.numeric(catVar), y=metVar, fill=factor(catVar))) + 
  geom_boxplot()
xorigin <- ggplot_build(p)$panel$ranges[[1]][[1]][1]
rm(p)


ggplot(ds, aes(x=as.numeric(catVar), y=metVar, fill=factor(catVar))) + 
  geom_boxplot() + 
  scale_x_continuous(breaks=c(xorigin, seq(1,length(levels(ds$catVar)))), 
                     labels=xlabs) +
  theme(axis.ticks.x=element_line(color=c('white', 
                                          rep('black', length(xlabs[-1]))))) +
  xlab(catName) +
  ylab(metName) +
  labs(fill=catName) 

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM