How to specify arguments in ggplot function? - r

I faced a problem that R does't see the argument I specify in ggplot function. Here is the code I use:
s_plot <- function(data, aaa, bbb,){
ggplot(data, aes(x = aaa, y = bbb))+geom_point(size=2, shape=8, col="red")
}
As a result I got an error:
object aaa not found
What's the problem? How to resolve it?
Thanks a lot.
UPD:
Sorry, but I provide you with the simplest example and it doesn't translate the whole problem.
Here is the full code I use:
s_plot <- function(data, n_after, perc_cap, n_xlab, n_ylab, x_min){
ggplot(data, aes(x={{n_after}}, y={{perc_cap}})) + geom_point(size=2, shape=8, col="red")+
xlab(n_xlab)+ ylab(n_ylab)+xlim(x_min, 1.1*max(data$n_after))+ ylim(0, 1.1*max(data$perc_cap))+
geom_text(aes(x=n_after, y=perc_cap, label = NAME), hjust=0, vjust=-1.5)+
geom_vline(xintercept=8, col = "darkgreen",lty=2, size=1)+
geom_text(aes(x=8, label=label, y=20), colour="steelblue", angle=90, hjust=-1)+
theme(axis.title.y = element_text(size=15),
axis.title.x = element_text(size=15))
As you may see n_after and perc_cap are mentioned in several places. And this probably is the source of problem. How to resolve it in this particular case?

You can use the {{ }} operator. As in the example:
f <- function (data, x) {ggplot(data= data, aes(x={{x}})) + geom_bar()}
f(mtcars, gear)

Related

Adding superscript to axis tick labels that contain / and ; for a ggplot2 object

I'm trying to create axis tick labels for addition to a ggplot2 object using scale_x_discrete(labels = ). I've tried using bquote and the expression function for superscripts however I keep getting error messages saying unexpected symbol when I add / and ; signs into the string. Does anyone know a way around this? I've attached an example of one of the tick labels I want to include. If you need any more information please let me know, thanks.
This should be possible with ggtext if you formulate your formatting with markdown:
library(ggplot2); library(ggtext)
mtcars2 <- mtcars
mtcars2$x = ifelse(mtcars2$gear == 5, "Cul3<sup>+/+</sup>;Ctrl", mtcars2$gear)
ggplot(mtcars2, aes(x, mpg)) +
geom_point() +
theme(axis.text.x = element_markdown(size = 18))
Here's a way using scale_x_discrete and expression with plotmath.
library(ggplot2)
ggplot(ToothGrowth, aes(supp, len)) +
geom_bar(stat = "sum", show.legend = FALSE)+
scale_x_discrete(breaks = c("OJ", "VC"),
labels = c(expression(Cul3^"+/+"*";Ctrl"), "Some other label"))+
theme(axis.text.x = element_text(size = 18))
Created on 2022-10-04 with reprex v2.0.2

Error- State_count() must not be used ,. How to solve this?

She wants to find out crimes in the USA for various states. So she plots the data set "USArrests" to construct a bar chart of the number of murders in different states.
Following command is giving error :
ggplot(USArrests, aes(x = row.names(USArrests), y = USArrests$Murder, lab)) + geom_bar() + theme(axis.text.x=element_text(angle=90, hjust=1))
Error :
"stat_count() must not be used with a y aesthetic". What can she do to correct this?
Should I remove row.names — it should be x = USArrests$State ??
Should I use theme(axis.angle.x = 90) instead of current one?
Will geom_histogram() be better than Geom_bar?
Or Should I use geom_col() instead of geom_bar()?
Please do suggest correct command. Thanks
This is a very common issue, please see this. Just use geom_col instead of geom_bar, and also add row.names as a new variable to avoid further problems:
USArrests$states <- row.names(USArrests)
ggplot(USArrests, aes(x = states, y = Murder)) +
geom_col() +
theme(axis.text.x=element_text(angle=90, hjust=1))

R ggplot2: Line overlayed on Bar Graph (from separate data frames)

I have a bar graph coming from one set of monthly data and I want to overlay on it data from another set of monthly data in the form of a line. Here is a simplified example (in my data the second data set is not a simple manipulation of the first):
library(reshape2)
library(ggplot2)
test<-abs(rnorm(12)*1000)
test<-rbind(test, test+500)
colnames(test)<-month.abb[seq(1:12)]
rownames(test)<-c("first", "second")
otherTest<-apply(test, 2, mean)
test<-melt(test)
otherTest<-as.data.frame(otherTest)
p<-ggplot(test, aes(x=Var2, y=value, fill=Var1, order=-as.numeric(Var2))) + geom_bar(stat="identity")+
theme_bw() + theme(panel.border = element_blank(), panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black")) +
ggtitle("Test Graph") +
scale_fill_manual(values = c(rgb(1,1,1), rgb(.9,0,0))) +
guides(fill=FALSE) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
works great to get the bar graph:
but I have tried multiple iterations to get the line on there and can't figure it out (like this):
p + geom_line(data=otherTest,size=1, color=rgb(0,.5,0)
Also, if anybody knows how I can make the bars in front of each other so that all you see is a red bar of height 500, I would appreciate any suggestions. I know I can just take the difference between the two lines of the matrix and keep it as a stacked bar but I thought there might be an easy way to put both bars on the x-axis, white in front of red. Thanks!
You have a few problems to deal with here.
Directly answering your question, if you don't provide a mapping via aes(...) in a geom call (like your geom_line...), then the mapping will come from ggplot(). Your ggplot() specifies x=Var2, y=value, fill=Var1.... All of these variable names must exist in your data frame otherTest for this to work, and they don't right now.
So, you either need to ensure that these variable names exist in otherTest, or specify mapping separately in geom_line. You might want to read up about how these layering options work. E.g., here's a post of mine that goes into some detail.
If you go for the first option, some other problems to think about:
is Var2 a factor with the same levels in both data frames? It probably should be.
to use geom_line as you are, you might need to add group = 1. See here.
Some others too, but here's a brief example of what you might do:
library(reshape2)
library(ggplot2)
test <- abs(rnorm(12)*1000)
test <- rbind(test, test+500)
colnames(test) <- month.abb[seq(1:12)]
rownames(test) <- c("first", "second")
otherTest <- apply(test, 2, mean)
test <- melt(test)
otherTest <- data.frame(
Var2 = names(otherTest),
value = otherTest
)
otherTest$Var2 = factor(otherTest$Var2, levels = levels(test$Var2))
ggplot(test, aes(x = Var2, y = value, group = 1)) +
geom_bar(aes(fill = Var1), stat="identity") +
geom_line(data = otherTest)

Independent strip themes for ggplot2 facet_wrap using more than one variable

Is it possible to have independent strip themes for each variable used in ggplot2 facet_wrap?
Take this chunk of code as an example:
p1 <- ggplot(mpg, aes(displ, hwy)) +
geom_point() +
facet_wrap(c("cyl", "drv"), labeller = "label_both")
plot(p1)
I would want to have upper strip ('cyl') with a different theme - say, in bold. Additionally, I might want to make 'drv' italic and with a different font type and size. How could I do that?
I was thinking something in the lines of:
p1 <- p1 + theme(strip.text.variable1 = element_text(face = 'bold'),
strip.text.variable2 = element_text(face = 'italic', size = 8)
)
Unfortunately, I couldn't find anything like this in the docs or previous questions.
Cheers
Edit: I made the question a bit more general to be of further help to the community.
Ostensibly you should be able to make a new function based on label_both to return bold labels, but so far my attempts have ended with the dreaded Error in variable[[i]] : subscript out of bounds.
An alternative to this is to build a function to make the label you want. This is much like this answer. In this function you add the prefix to the values of the variable and make them bold.
make_labels = function(string, prefix = "cyl: ") {
x = paste0(prefix, as.character(string))
do.call(expression, lapply(x, function(y) bquote(bold(.(y)))))
}
Now use this function within as_labeller for the "cyl" variable in facet_wrap. You want to change the default labeller within as_labeller to label_parsed so the expression is parsed correctly. Use label_both for the other variable.
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
facet_wrap(c("cyl", "drv"),
labeller = labeller(cyl = as_labeller(make_labels, default = label_parsed),
drv = label_both))

Remove legend title in ggplot

I'm trying to remove the title of a legend in ggplot2:
df <- data.frame(
g = rep(letters[1:2], 5),
x = rnorm(10),
y = rnorm(10)
)
library(ggplot2)
ggplot(df, aes(x, y, colour=g)) +
geom_line(stat="identity") +
theme(legend.position="bottom")
I've seen this question and none of the solutions there seem to work for me. Most give an error about how opts is deprecated and to use theme instead. I've also tried various versions of theme(legend.title=NULL), theme(legend.title=""), theme(legend.title=element_blank), etc. Typical error messages are:
'opts' is deprecated. Use 'theme' instead. (Deprecated; last used in version 0.9.1)
'theme_blank' is deprecated. Use 'element_blank' instead. (Deprecated; last used in version 0.9.1)
I'm using ggplot2 for the first time since version 0.9.3 was released and I'm finding it difficult to navigate some of the changes...
You were almost there : just add theme(legend.title=element_blank())
ggplot(df, aes(x, y, colour=g)) +
geom_line(stat="identity") +
theme(legend.position="bottom") +
theme(legend.title=element_blank())
This page on Cookbook for R gives plenty of details on how to customize legends.
This works too and also demonstrates how to change the legend title:
ggplot(df, aes(x, y, colour=g)) +
geom_line(stat="identity") +
theme(legend.position="bottom") +
scale_color_discrete(name="")
Another option using labs and setting colour to NULL.
ggplot(df, aes(x, y, colour = g)) +
geom_line(stat = "identity") +
theme(legend.position = "bottom") +
labs(colour = NULL)
Since you may have more than one legends in a plot, a way to selectively remove just one of the titles without leaving an empty space is to set the name argument of the scale_ function to NULL, i.e.
scale_fill_discrete(name = NULL)
(kudos to #pascal for a comment on another thread)
For Error: 'opts' is deprecated. Use theme() instead. (Defunct; last used in version 0.9.1)'
I replaced opts(title = "Boxplot - Candidate's Tweet Scores") with
labs(title = "Boxplot - Candidate's Tweet Scores"). It worked!

Resources