Coloring a specific label in ggplot depending on the value of the id variable on long data (regardless of the line number)

Let's say I have a long dataset and I would like to color a specific label along the x axis. In the case of the example below, I would like to color the shortcut for Valiant.

# Packs
require(ggplot2)
require(reshape2)

# Data and trans
data(mtcars)
mtcars$model <- rownames(mtcars)
mtcars <- melt(mtcars, id.vars = "model")

# Some chart
ggplot(data = subset(x = mtcars, subset = mtcars$variable == "cyl"), 
       aes(x = model, y = value)) +
    geom_bar(stat = "identity") +
    theme(axis.text.x = element_text(angle = 90, 
                                     colour =
                                         ifelse(mtcars$model == "Valiant",
                                                "red","black")))

      

The code below shows the diagram below which is erroneous because the wrong label is colored.

Wrong label

The reason is quite simple, since the created one ifelse

does not correspond to the order on the axis. I can fix the code by forcing to ggplot

color a specific line. The code below colors the right label as in the specific data.frame

used for the chart, the line with the value Valiant 31 .

# Fixed chart
ggplot(data = subset(x = mtcars, subset = mtcars$variable == "cyl"), 
       aes(x = model, y = value)) +
    geom_bar(stat = "identity") +
    theme(axis.text.x = element_text(angle = 90, 
                                     colour =
                                         ifelse(as.numeric(rownames(mtcars)) == 31,
                                                "red","black")))

      

Fixed label

It is clear that this solution is highly impractical. In fact, I have a huge number of observations with multiple columns (geo, gender, indicator, value, etc.). This data is then filtered through the subset, and various parameters are passed to the settings aes

. Trying to figure out which line should be colored is a nightmare. I am looking for a solution that would allow me to:

  • It is pointed out relatively effortlessly that a particular observation should be colored without trying to use line numbers.
  • Ideally, I would like to use id

    with some line to indicate the text that I want to highlight
  • I would like to encapsulate the solution in code ggplot2

    , I do not want to create separate subsets of the data just to get the coloration vector as I will be doing this several times. This will result in unnecessary multiple objects.
  • In practice, I want the solution to work like this: no matter what's on the graph, when you find that line on the x-axis, make it red
+3


source to share


1 answer


The reason the first one is incompatible is that it is mtcars$model

much longer than the subset you are drawing, so the color vector ifelse(mtcars$model == "Valiant","red","black")

is 352 long, but the subset you are drawing is 32 in length. The same problem exists with your second example, although in this in the case of additional elements colour

(they are all "black") are discarded anyway, so you won't notice.

Unfortunately it theme(...)

doesn't seem to be evaluated with the data column names available to it (i.e. can't just do colour=ifelse(model == "Valiant", "red", "black")

directly in the call theme(...)

)

One option is to make a model

factor and filter by levels(..) == "Valiant"

. If you have a long dataframe, your id variable is most likely a factor anyway (or it would make sense to have one).



mtcars$model = factor(mtcars$model)
ggplot(data=subset(mtcars, variable == 'cyl'), aes(x=model, y=value)) +
    geom_bar(stat="identity") +
    theme(axis.text.x=element_text(angle=90,
              colour=ifelse(levels(mtcars$model) == 'Valiant', 'red', 'black')))

      

(your problem has to do with feeding subset()

to ggplot as your data and then not being able to revert to that particular subset in the call theme

. I don't know if there is a tricky way to do this).

+1


source







All Articles