'How to adjust label position above only the negative bars in a grouped bar plot with positive and negative bars (ggplot)?

I have a grouped bar plot with positive and negative values for the y axis, and I would like to have the labels ABOVE all bars, so also for the negative bars. I tried the vjust=ifelse command, but it did not work, giving me the error message "Aesthetics must be either length 1 or the same as the data: vjust" I also tried to make a new object (adj) and use that in the vjust = 'adj' command, but did not work either.

This is part of my data (the whole data set is in an excel file and I use the "read_csv" command to load it in to R):

Soil    Condition   Extractant  Treatment   Element Stabileff   SD  Diff
organic layer   100% WHC    demi water  nZVI    As  36  0   *
organic layer   100% WHC    demi water  nZVI-BC As  31  0   *
organic layer   100% WHC    demi water  Fe/FeS-BC   As  -159    0   *
organic layer   100% WHC    demi water  BC  As  -76 0   *
organic layer   100% WHC    demi water  Control As  0   0   
organic layer   100% WHC    rainwater   nZVI    As  49  0   *
organic layer   100% WHC    rainwater   nZVI-BC As  48  0   *
organic layer   100% WHC    rainwater   Fe/FeS-BC   As  -52 0   *
organic layer   100% WHC    rainwater   BC  As  -46 0   *
organic layer   100% WHC    rainwater   Control As  0   0   
organic layer   100% WHC    demi water  nZVI    Sb  83  0   *
organic layer   100% WHC    demi water  nZVI-BC Sb  68  0   *
organic layer   100% WHC    demi water  Fe/FeS-BC   Sb  92  0   *
organic layer   100% WHC    demi water  BC  Sb  -31 0   *
organic layer   100% WHC    demi water  Control Sb  0   0   
organic layer   100% WHC    rainwater   nZVI    Sb  62  0   *
organic layer   100% WHC    rainwater   nZVI-BC Sb  74  0   *
organic layer   100% WHC    rainwater   Fe/FeS-BC   Sb  70  0   *
organic layer   100% WHC    rainwater   BC  Sb  1   0   
organic layer   100% WHC    rainwater   Control Sb  0   0   

I am using this code (which works fine but the label on the negative bar is inside the bar):

single_plot <- function(.df,                    # data frame
                    c.xgroup = "Treatment", # Column names
                    c.mean = "Stabileff",
                    c.bars = "Extractant",
                    c.error.bars = "SD",
                    grid.cols = "Condition",
                    grid.rows = "Soil",
                    c.differences = "Diff",
                    color.scale = "Paired"){
dodging <- 0.6
ggplot(data = .df,
       aes(x = !!ensym(c.xgroup),
           y = !!ensym(c.mean),
           fill = !!ensym(c.bars))) +
geom_bar(stat='identity',
         position = position_dodge(dodging),
                      width=0.6) +
geom_errorbar(aes(ymax = !!ensym(c.mean) + !!ensym(c.error.bars),
                  ymin = !!ensym(c.mean) - !!ensym(c.error.bars)),
              position = position_dodge(dodging),
              width=0) +
facet_grid(cols = vars(!!ensym(grid.cols)),
           rows = vars(!!ensym(grid.rows))) +
geom_text(aes(y = !!ensym(c.mean) + !!ensym(c.error.bars),
              label = !!ensym(c.differences)),
          size = 4, vjust = -0.5,
          position = position_dodge(dodging)) +
          theme_bw() +
    theme(axis.text.x = element_text(size=14, face="bold", angle = 90),
          axis.text.y = element_text(size=14, face="bold"),
          axis.title.y=element_text(size=14,face="bold"))     +
    scale_fill_brewer(palette = color.scale)}

e.data <- mutate(e.data,
   Treatment = parse_factor(Treatment,
                            levels = c('Control',
                                       'nZVI',
                                       'nZVI-BC',
                                       'Fe/FeS-BC',
                                       'BC')))

e.data$Condition = factor(e.data$Condition, levels=c('50% WHC','100% WHC'))
e.data$Soil = factor(e.data$Soil, levels=c('organic layer','mineral layer'))

cacl.data <- filter(e.data, Extractant == '0.01 M CaCl2')
main.data <- filter(e.data, Extractant != '0.01 M CaCl2') %>%
mutate(Extractant = parse_factor(Extractant,
                                 levels = c('demi water',
                                            'rainwater')))

list.elements <- c('As', 'Sb', 'l')
main.plots <- list()
for(symb in list.elements){
if(symb == 'l'){ ## Get legends
    main.plots[[symb]] <- get_legend(main.plots[[1]] +
                  theme(legend.position = "right"))
}
else{ ## Make plots
    main.plots[[symb]] <- filter(main.data, Element == symb) %>%
        single_plot() +
        theme(legend.position = "none") +
        labs(title = symb,
             y = paste('stabilization efficiency (%)'), size=12, face="bold",
             x = NULL)
            }}

names(main.plots)

main.plots[['As']] <- main.plots[['As']] +
scale_y_continuous(limits = c(-160,160)) + 
     theme(strip.text = element_text(size = 18, face="bold"),
           plot.title = element_text(size = 30, face="bold"))
plot_grid(main.plots[['As']])

Please help, thank you!!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source