ggplot2 facet_wrap doesn't find a variable but shape does - r

I'm running in a bit of a problem plotting some data with ggplot2: I want to use a facet_wrap over a variable AdultInputProp, but R doesn't find the variable and instead returns an Error in as.quoted(facets) : object 'AdultInputProp' not found. Now I understand that this simply means that R can't find this variable in the dataset used to plot, but if I ask ggplot2 to instead use the same variable for to create a shape scale, it works just fine. Any idea what the problem might be?
Sorry, I'm not too sure how to make a minimal working example with a generated df from scratch, so here's the df I'm using, and the code bellow. I've also tried using facet_grid instead of facet_wrap but ran into the same problem.
The code here with facets returns the above-mentioned error:
df.plot.GBPperAIP <- ggplot(df.sum.GBPperAIP,
aes(x=TestIteration, y=Error,
colour=GoalBabblingProp,
group=interaction(GoalBabblingProp,
AdultInputProp))) +
facet_wrap(AdultInputProp) +
xlab("Step") + ylab("Mean error") + theme_bw(base_size=18) +
scale_colour_discrete(name = "Goal babbling proportion") +
geom_line(position = position_dodge(1000)) +
geom_errorbar(aes(ymin=Error-ci,
ymax=Error+ci),
color="black", width=1000,
position = position_dodge(1000)) +
geom_point(position = position_dodge(1000),
size=1.5, fill="white")
This other code, exactly the same except for the facet_wrap line deleted and with shape added works fine:
df.plot.GBPperAIP <- ggplot(df.sum.GBPperAIP,
aes(x=TestIteration, y=Error,
colour=GoalBabblingProp,
shape=AdultInputProp,
group=interaction(GoalBabblingProp,
AdultInputProp))) +
xlab("Step") + ylab("Mean error") + theme_bw(base_size=18) +
scale_colour_discrete(name = "Goal babbling proportion") +
geom_line(position = position_dodge(1000)) +
geom_errorbar(aes(ymin=Error-ci,
ymax=Error+ci),
color="black", width=1000,
position = position_dodge(1000)) +
geom_point(position = position_dodge(1000),
size=1.5, fill="white")

facet_wrap expects a formula, not just a naked variable name. So you should change it to
...
facet_wrap(~ AdultInputProp) +
...

Related

Legends in ggplot

I am trying plot this data, and the line graph is correct, but I can't make the legend show up. Any thoughts?
ggplot(data, aes(x=time_months, size=I(1))) +geom_line(aes(y=monthly_net_revenue, color=I("blue"))) +
geom_line(aes(y=cumsum(discounted_monthly_net_revenue), color=I("purple"))) +
geom_line(aes(y=monthly_expenses, color=I("red"))) +
geom_line(aes(y=cumsum(monthly_revenue), color=I("green")))
This will probably work for you
ggplot(data, aes(x=time_months, size=I(1))) +
geom_line(aes(y=monthly_net_revenue, color="blue")) +
geom_line(aes(y=cumsum(discounted_monthly_net_revenue), color="purple")) +
geom_line(aes(y=monthly_expenses, color="red")) +
geom_line(aes(y=cumsum(monthly_revenue), color="green")) +
scale_color_identity(guide = "legend")
The scale_color_identity() uses the values you pass to color= directly as the color rather than treating them like a group name. You don't need I() with this method.

Create a ggplot geom_boxplot when third variable=x

I think this is a fairly simple question, I just can't figure it out for the life of me.
I am making a boxplot using the following code;
ggplot(data, aes(gear, length)) + geom_boxplot() + xlab('Gear Type') +
ylab('Size (cm)') + ggtitle("Catch Characterization") +
theme(plot.title = element_text(hjust = 0.5))
This produces an aggregated boxplot for my entire dataset, I would like to be able to produce the same boxplot for two subsets of my dataset. Specifically I have another column "action" with either the character "D" or "K". For example MySQL mind wants to just add in a WHERE clause (however I know that is not how it works) such as;
ggplot(data, aes(gear, length, WHEREaction=D)) + geom_boxplot() + xlab('Gear Type') +
ylab('Size (cm)') + ggtitle("Catch Characterization") +
theme(plot.title = element_text(hjust = 0.5))
Edit, I am able to use facet_wrap to parse out and graph based on "action" however I am curious how I could just make one graph where of (length, gear) where "action = D". I know I can fairly easily just restructure my data just wondering if there is a simpler/quicker way to do so with the aggregated data set?
Edit again, think I figured it out by piecing a few things together, I ended up using this code and it seems to be giving me the appropriate graphs;
ggplot(aggdata[aggdata$action == "D",], aes(gear, length)) +
geom_boxplot() + xlab('Gear') + ylab('Size (cm)') +
ggtitle("Discard Characterization") +
theme(plot.title = element_text(hjust = 0.5))

Creating Error Bars in R (ggplot2)

I've been working on creating a bar graph with error bars to depict group differences for a dataset that I have. But the error bars are coming out funky, in that they are appearing further above the bar and in the middle of a bar.
My code:
ggplot(MRS_Hippo_NAA_Cre_Data_copy, aes(Type, Hippo_6_9NAACre, fill=Type)) +
geom_bar(stat="summary", fun.y="mean", colour="black", size=.3) +
geom_errorbar(aes(ymin=meanNAA-NAAse, ymax=meanNAA+NAAse), width=.2,
position=position_dodge(.9)) + labs(x="Group", y="Right Posterior NAA/Cre") +
scale_fill_manual(values=c("#0072B2", "#D55E00"), name="Group") + theme(text =
element_text(size=18))`
This produced this graph:
I calculated the standard error by using the following function:
std <- function(x) sd(x)/sqrt(length(x))
x=Hippo_6_9NAACre
Not sure why the graph is producing funky error bars. Can anyone help or provide insight?
I had very recently a similar problem.
To solve it, first of all you may want to remove the layer
geom_errorbar(aes(ymin=meanNAA-NAAse,
ymax=meanNAA+NAAse), width=.2, position=position_dodge(.9))
and rather use a layer with the statsummary function again. That will generate the error bars separated for group.
As you want the bars indicating the standard error, you must create an appropriate function that returns the needed values, such that can be used from statsummary.
Find below a working example with iris dataset.
library(ggplot2)
## create a function for standard error that can be used with stat_summary
# I created the function inspecting the results returned by 'mean_cl_normal' that is the
# function used in some examples of stat_summary (see ?stat_summary).
mean_se = function(x){
se = function(x){sd(x)/sqrt(length(x))}
data.frame(y=mean(x), ymin=mean(x)+se(x), ymax=mean(x)-se(x))
}
## create the plot
p = ggplot(iris, aes(x = Species, y = Sepal.Length), stat="identity") +
stat_summary(fun.y = mean, geom = "col", fill = "White", colour = "Black", width=0.5) +
stat_summary(fun.data = mean_se, geom = "errorbar", width=0.2, size=1)
# print the plot
print(p)

Creating histogram on R

I am trying to create a graph on R but keep getting this error...
Error in inherits(mapping, "uneval") : object 'EI.TOT' not found
I have put in this command:
hist.1 <- ggplot(data, EI.TOT) + theme(legend.position = "none") + geom_histogram(aes(y=..density..), colour="black", fill="white") + labs(x="EI.TOT", y = "Density")
EI.TOT is the header of one of my columns. I have run a regression using these values but when I want to create a histogram is says that this column is not found.
Your trouble is that you dont specify your aes correctly. Try this code, let me know if it does not work on your data.
library(ggplot2)
data <- data.frame(EI.TOT =rnorm(60))
hist.1 <- ggplot(data=data) +
theme(legend.position = "none") +
geom_histogram(aes(EI.TOT),colour="black", fill="white", binwidth = 0.5) +
labs(x="EI.TOT", y = "Density")
hist.1
Change bindwidth to change the breaks in the plot.

Apply coord_flip() to single layer

I would like to have a boxplot showing the same distribution underneath my histogram.
The code below almost works, but coord_flip() is being applied to all layers, instead of just the geom_boxplot layer.
plot1<-ggplot(newdatahistogram, aes_string(x=newdatahistogram[RawLocation])) +
xlab(GGVar) + ylab("Proportion of Instances") +
geom_histogram(aes(y=..density..), binwidth=1, colour="black", fill="white",origin=-0.5) +
scale_x_continuous(limits=c(-3,6), breaks=seq(0,5,by=1), expand=c(.01,0)) +
geom_boxplot(aes_string(x=-1, y=newdatahistogram[RawLocation])) + coord_flip()
How can I apply coord_flip() to a single layer?
Thank you!
I got it to work with a bit of a hack;
plot1 <- ggplot(newdatahistogram, aes_string(x=newdatahistogram[RawLocation], fill=(newdatahistogram[,"PQ"]))) +
xlab(GGVar) + ylab("Proportion of Observation") +
geom_histogram(aes(y=..density..), binwidth=1, colour="black", origin=-0.5) +
scale_x_continuous(limits=c(-1,6), breaks=seq(0,5,by=1), expand=c(.01,0)) +
scale_y_continuous(limits=c(-.2,1), breaks=seq(0,1,by=.2))
theme(plot.margin = unit(c(0,0,0,0), "cm"))
plot_box <- ggplot(newdatahistogram) +
geom_boxplot(aes_string(x=1, y=newdatahistogram[RawLocation])) +
scale_y_continuous(breaks=(0:5), labels=NULL, limits=c(-1,6), expand=c(.0,-.03)) +
scale_x_continuous(breaks=NULL) + xlab(NULL) + ylab(NULL) +
coord_flip() + theme_bw() +
theme(plot.margin = unit(c(0,0,.0,0), "cm"),
line=element_blank(),text=element_blank(),
axis.line = element_blank(),title=element_blank(), panel.border=theme_blank())
PB = ggplotGrob(plot_box)
plot1 <- plot1 + annotation_custom(grob=PB, xmin=-1.01, xmax=5.95, ymin=-.3,ymax=0)
This saves the rotated boxplot as a grob object and inserts it into the plot under the histogram.
I needed to play with the expansion element a bit to get the scales to line up,
but it works!
Seriously though, I think ggplot should have a horizontal boxplot available without cord_flip()... I tried to edit the boxplot code, but it was way too difficult for me!
Tried to post image, but not enough reputation
You can't: coord_flip always acts on all layers. However, you do have two alternatives:
The solution here shows how to use grid.arrange() to add a marginal histogram. (The comments in the question also link to a nice base-R way to do the same thing)
You could indicate density using a rug plot on of the four sides of the plot with plot1 + geom_rug(sides='r')
ggplot(mpg, aes(x=class, y=cty)) +
geom_boxplot() + geom_rug(sides="r")

Resources