﻿ Issue When Passing Variable With Dollar Sign Notation (\$) to Aes() in Combination With Facet_Grid() or Facet_Wrap() - ITCodar

# Issue When Passing Variable With Dollar Sign Notation (\$) to Aes() in Combination With Facet_Grid() or Facet_Wrap()

## Issue when passing variable with dollar sign notation (\$) to aes() in combination with facet_grid() or facet_wrap()

tl;dr

Never use `[` or `\$` inside `aes()`.

Consider this illustrative example where the facetting variable `f` is purposely in a non-obvious order with respect to `x`

``d <- data.frame(x=1:10, f=rev(letters[gl(2,5)]))``

Now contrast what happens with these two plots,

``p1 <- ggplot(d) +  facet_grid(.~f, labeller = label_both) +  geom_text(aes(x, y=0, label=x, colour=f)) +  ggtitle("good mapping") p2 <- ggplot(d) +  facet_grid(.~f, labeller = label_both) +  geom_text(aes(d\$x, y=0, label=x, colour=f)) +  ggtitle("\$ corruption") `` We can get a better idea of what's happening by looking at the data.frame created internally by ggplot2 for each panel,

`` ggplot_build(p1)[["data"]][][,c("x","PANEL")]    x PANEL1   6     12   7     13   8     14   9     15  10     16   1     27   2     28   3     29   4     210  5     2 ggplot_build(p2)[["data"]][][,c("x", "PANEL")]    x PANEL1   1     12   2     13   3     14   4     15   5     16   6     27   7     28   8     29   9     210 10     2``

The second plot has the wrong mapping, because when ggplot creates a data.frame for each panel, it picks x values in the "wrong" order.

This occurs because the use of `\$` breaks the link between the various variables to be mapped (ggplot must assume it's an independent variable, which for all it knows could come from an arbitrary, disconnected source). Since the data.frame in this example is not ordered according to the factor `f`, the subset data.frames used internally for each panel assume the wrong order.

## facet_wrap plotting incorrect x axis co-ordinates

`ggplot` has a `data` argument for a reason. When you re-specify the data frame inside `aes()`, it overrides the subsetting and ordering done for the faceting. Just don't re-specify the name of the data frame (no `mydata\$column`) and everything works fine:

``ggplot(ZoutliersM,       aes(x = leftPos,           y = as.numeric(Def.x),           xend = leftPos,           yend = 0)) +  geom_point(fill = "magenta", size = 2, colour = "red") +  facet_wrap(~chr)`` Now we can see that in the "22" facet, the point is a little under 10M, as expected.

Two other notes:

• specifying a "fill" for `geom_point` won't do anything unless you also use a shape that has separate fill and colors, such as `shape = 21`

• In your `dput` data, `Def.x` is already numeric, so you don't need to convert it. If it was a factor previously, make sure you convert with `as.numeric(as.character(Def.x))`, otherwise you'll simply be taking the levels rather than the value to numeric.

## Wrong colour when using facet_wrap()

Don't use `\$` notation in `ggplot` aesthetics. Use raw variable names instead:

``qplot(a,b,data=df,geom='point',color=factor(c)) +   facet_wrap(~d) +   scale_colour_manual(values=c("blue","orange"))``

## facet_grid weird rearrangement of values

Do it like here (in `aes` `fill` should be the column NAME not the VECTOR):

``plot <- ggplot(mockdata, aes(variable, Measurement, fill = plotval)) +     geom_tile(colour = "dark red")  +     facet_grid(category~type, scales='free', space='free') +     scale_fill_gradient2(limits=c(-20, 20),high = "firebrick3", low = "dodgerblue4") +     theme_minimal() +     theme(axis.text.x=element_text(size=28, angle=90),           axis.text.y=element_text(size=28, face = "italic"),          strip.text.x=element_blank(),          strip.text.y=element_text(size=20, angle=0)) +     labs(title="", x="", y="", fill="")``

## ggplot facet_grid data.table order bug

Just remove all dat.rel\$ inside the plot configuration makes the facet_grids work like desired, indipendently from the row order.

## Problem with ggplot when reassigning variables for data

ggplot2 saves the data.frame passed to the `data` parameter in the ggplot object. For anything referenced in `aes` that is not in this data.frame it has to rely on scoping to find it when the plot is build (each time it is printed).

So, just make sure that `resp` is passed to the `data` parameter, too.

``resp <- iris\$Sepal.Lengthp <- ggplot(cbind(iris, resp), aes(x = Petal.Length, y = resp))+  geom_point()presp <- iris\$Sepal.Widthp#same plot``

PS: Your example with the function works, because the plot environment of `q1` and `q2` are environments created during the function call whereas the plot environment of `p` is the global environment. Compare `p\$plot_env` and `q1\$plot_env` and check out `ls(q1\$plot_env)`.

## Issue when passing variable with dollar sign notation (\$) to aes() in combination with facet_grid() or facet_wrap()

tl;dr

Never use `[` or `\$` inside `aes()`.

Consider this illustrative example where the facetting variable `f` is purposely in a non-obvious order with respect to `x`

``d <- data.frame(x=1:10, f=rev(letters[gl(2,5)]))``

Now contrast what happens with these two plots,

``p1 <- ggplot(d) +  facet_grid(.~f, labeller = label_both) +  geom_text(aes(x, y=0, label=x, colour=f)) +  ggtitle("good mapping") p2 <- ggplot(d) +  facet_grid(.~f, labeller = label_both) +  geom_text(aes(d\$x, y=0, label=x, colour=f)) +  ggtitle("\$ corruption") `` We can get a better idea of what's happening by looking at the data.frame created internally by ggplot2 for each panel,

`` ggplot_build(p1)[["data"]][][,c("x","PANEL")]    x PANEL1   6     12   7     13   8     14   9     15  10     16   1     27   2     28   3     29   4     210  5     2 ggplot_build(p2)[["data"]][][,c("x", "PANEL")]    x PANEL1   1     12   2     13   3     14   4     15   5     16   6     27   7     28   8     29   9     210 10     2``

The second plot has the wrong mapping, because when ggplot creates a data.frame for each panel, it picks x values in the "wrong" order.

This occurs because the use of `\$` breaks the link between the various variables to be mapped (ggplot must assume it's an independent variable, which for all it knows could come from an arbitrary, disconnected source). Since the data.frame in this example is not ordered according to the factor `f`, the subset data.frames used internally for each panel assume the wrong order.

## error: ggplot2 facet is plotting incorrect values

The key is to adjust the data before calling ggplot() and not to keep calling "df\$" inside ggplot. Otherwise certain errors are more likely to happen (e.g. factor orders can get mixed). To fix that in this case, you can try this:

``require(ggplot2)df\$exp_fit <- exp(df\$fit)df\$exp_lower <- exp(df\$lower)df\$exp_upper <- exp(df\$upper)df\$Type <- as.factor(df\$Type)df\$ZQVT <- as.factor(df\$ZQVT)ggplot(df, aes(x=ZMemScore, y=exp_fit,               color=Type)) +  geom_ribbon(aes(ymin=exp_lower, ymax=exp_upper,                   color=NA, fill=Type),               linetype=1, alpha=0.3) +   geom_line(aes(linetype=Type), size=1.2) +  xlab("ZMemScore") + ylab("Predicted RT (ms)") +   labs(color="Type", subtitle="ZQVT") +  facet_grid(. ~ ZQVT) +  scale_linetype_discrete(name='Type', labels=c('Nonword','Real Word')) +  theme_classic() +   scale_color_manual(values=c("black","firebrick2")) +   theme(plot.subtitle = element_text(hjust=0.5)) +  theme(text = element_text(size=14))+  guides(fill=FALSE, color=FALSE)``

Output: Sample data:

``require(data.table)df <- fread("ZMemScore ZQVT Type fit se lower upper  -1 -2 LDTNW 7.029661 0.04961080 6.932423 7.126900   0 -2 LDTNW 7.130045 0.03618878 7.059115 7.200976   1 -2 LDTNW 7.230430 0.05005473 7.132321 7.328538   2 -2 LDTNW 7.330814 0.07777387 7.178375 7.483253  -1 -1 LDTNW 6.953625 0.03015198 6.894526 7.012723   0 -1 LDTNW 7.021205 0.02288979 6.976340 7.066069   1 -1 LDTNW 7.088784 0.03319670 7.023718 7.153851   2 -1 LDTNW 7.156364 0.05141379 7.055592 7.257137   -1 0 LDTNW 6.877588 0.02308945 6.832332 6.922844    0 0 LDTNW 6.912364 0.01719115 6.878669 6.946059    1 0 LDTNW 6.947139 0.02335335 6.901366 6.992912    2 0 LDTNW 6.981915 0.03581413 6.911718 7.052111   -1 1 LDTNW 6.801552 0.03651265 6.729986 6.873117    0 1 LDTNW 6.803523 0.02498816 6.754545 6.852500    1 1 LDTNW 6.805494 0.02890588 6.748837 6.862150    2 1 LDTNW 6.807465 0.04434635 6.720545 6.894385   -1 2 LDTNW 6.725515 0.05752647 6.612762 6.838269    0 2 LDTNW 6.694682 0.03886592 6.618504 6.770860    1 2 LDTNW 6.663848 0.04441321 6.576797 6.750899    2 2 LDTNW 6.633015 0.06852165 6.498711 6.767319  -1 -2 LDTRW 6.903851 0.04518178 6.815294 6.992409   0 -2 LDTRW 6.972785 0.03334094 6.907436 7.038134   1 -2 LDTRW 7.041719 0.04585878 6.951835 7.131603   2 -2 LDTRW 7.110653 0.07082106 6.971842 7.249464  -1 -1 LDTRW 6.806363 0.02755119 6.752362 6.860364   0 -1 LDTRW 6.855938 0.02116456 6.814455 6.897421   1 -1 LDTRW 6.905514 0.03046645 6.845799 6.965229   2 -1 LDTRW 6.955089 0.04690274 6.863158 7.047020   -1 0 LDTRW 6.708874 0.02124658 6.667230 6.750518    0 0 LDTRW 6.739091 0.01594271 6.707843 6.770339    1 0 LDTRW 6.769308 0.02146327 6.727240 6.811377    2 0 LDTRW 6.799525 0.03272497 6.735384 6.863667   -1 1 LDTRW 6.611386 0.03344309 6.545836 6.676935    0 1 LDTRW 6.622244 0.02302851 6.577108 6.667381    1 1 LDTRW 6.633103 0.02646563 6.581230 6.684976    2 1 LDTRW 6.643962 0.04035829 6.564858 6.723065   -1 2 LDTRW 6.513897 0.05253701 6.410923 6.616871    0 2 LDTRW 6.505397 0.03572626 6.435373 6.575422    1 2 LDTRW 6.496898 0.04058913 6.417342 6.576453    2 2 LDTRW 6.488398 0.06223723 6.366411 6.610384")``

## ggplot2 faceting - plots not reordered when labels reordered

The `factor` `levels` reordering that you used seems to work with that small example at least:

``library(ggplot2)dtf <- data.frame(day = c("Mon", "Tue", "Wed", "Thu",                          "Fri", "Sat", "Sun"),                  value = 1:7)ggplot(dtf, aes(x = value, y = value)) +     geom_point() + facet_wrap(~day)`` ``dtf\$day1 <- factor(dtf\$day, levels = c("Mon", "Tue", "Wed", "Thu",                                       "Fri", "Sat", "Sun"))ggplot(dtf, aes(x = value, y = value)) +     geom_point() + facet_wrap(~day1)`` Let's have a look at the structure of the data frame:

``str(dtf)# 'data.frame': 7 obs. of  3 variables:# \$ day  : Factor w/ 7 levels "Fri","Mon","Sat",..: 2 6 7 5 1 3 4# \$ value: int  1 2 3 4 5 6 7# \$ day1 : Factor w/ 7 levels "Mon","Tue","Wed",..: 1 2 3 4 5 6 7``

Values are the same but the order of factor levels has been changed.