简体   繁体   中英

Adding specific labels to a the top of columns on geom_bar in R

I have a database with a sample im working on. Im trying to get the code to add all the earnings for each variable (12 variables) and then display on top of each column an abbreviated version of the number because it is in the billions and it is two long. The problem seems to be that I can't use count because I have x and y in aesthetics, but if I cut one out then I can't make the graph. This is my code:

set.seed(180173)
renglones <- sample(1:nrow(Metro), size=300, replace = FALSE)
MuestraNE <- Metro[renglones, ]
View (MuestraNE)
summary(MuestraNE)

library(ggplot2)
library(reshape2)

ing = aggregate(.~ TIPO_INGRESO, FUN = sum, data=MuestraNE)

tot = colSums(ing[,3:14])
lblstot = c(tot[1]/100000000,tot[2]/100000000,tot[3]/100000000,tot[4]/100000000,
            tot[5]/100000000,tot[6]/100000000,tot[7]/100000000,tot[8]/100000000,
            tot[9]/100000000,tot[10]/100000000,tot[11]/100000000,tot[12]/100000000)
p <- as.numeric(lblstot)

gg <- melt(MuestraNE[ , 3:14])   
ggplot(gg, aes(x=variable, y=value)) + 
  geom_bar(fill = "orange", stat = "identity") + 
  ggtitle("Total por Línea de Metro")+
  geom_text(aes(y = p), vjust=-1, size = 3)+
  theme(axis.title = element_blank(), legend.position = "none",
        plot.title = element_text(hjust = 0.5, face = "bold"),
        axis.ticks = element_blank(), axis.text.y = element_blank(),
        axis.text.x = element_text(angle = 270, vjust = 0.3, hjust = -0.5,
                                   color = "black")) 

whenever I try to add some kind of format with geom_text() I always get an error saying:

Error: Aesthetics must be either length 1 or the same as the data (3600): y
Run `rlang::last_error()` to see where the error occurred.

I've tried everything I could find on google and in here but nothing seems to work, I's appreciate a lot if you guys could help me out. This is the link to my database The libstot part is what I'm trying to get on top of each column, ie tot 1 /10000000 on top of the first column, tot[2]/100000000 on top of the second column etcetera.

I think you need to specify the in geom_text(x=..?, y=p) Also try ggrepel

If its possible share your data in csv or the first rows of it.

Hope it is helpful

The following is a generic example. {ggplot} works well with (long) data frames. A good strategy is to prepare your dataframe to have also the labels included. If you provide a vector only for the labels, make sure that the length of the labels fit with the data you define (check alternative 2)

Two additional points

  • instead of geom_bar(... stat = "identity") you can now use geom_col()
  • aesthetics in ggplot can be inherited, thus you could move the aes(x = variable, y = value) into the ggplot() call. I keep it separate, so you can see that adding a new dataframe (option 2) allows you to handle the text as a "fully" separate layer. This might come handy in the long run/other problems/graphs you will produce.
df <- data.frame(
   variable = 1:12
  ,value = c(3,4,5,6,7,6,4,3,8,2,6,5)
)

# generate labels
lbl <- paste0(df$value, " B")
df <- df %>% mutate(label = lbl)

ggplot(data = df) +
  geom_col( aes(x = variable, y = value), fill = "orange") +          
  geom_text(aes(x = variable, y = value, label = label), vjust = 1)   # vjust offsets the label

在此处输入图像描述

Alternative:

If you opt for inheritence of the aesthetic mapping and what to provide a label vector "only". The code would read as follows:

# we call data and set the x and y mappings
ggplot(data = df, aes(x=variable, y= value)) + 
  geom_col(fill = "orange") +
  #------------- annotation layer ---------------------
  # the anchor points of the labels are inherited from ggplot() call 
  geom_text(aes(label = lbl), vjust = 1)

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