问题
I want to set the string N=xxx as the title of my figure, where xxx is the number of observations in the data frame that I pass as the data argument to ggplot(). In my current code, I explicitly pass that data frame a second time as an argument to sprintf() which I use inside of labs():
ggplot(mtcars, aes(mpg, hp)) +
labs(title=sprintf("N=%i", nrow(mtcars))) +
geom_point()
This does produce the desired title, but it won't work with more complex tasks: I use a dplyr pipe to construct the data frame that is being plotted, and as this is a time-consuming process, I wouldn't want to repeat the pipe a second time to obtain the number of rows like in the example.
So, how do I access the data frame that has been passed as an argument to ggplot() from within the argument specifications of the functions that are used to modify the plot?
回答1:
mtcars %>% {
ggplot(., aes(mpg, hp)) +
labs(title = paste("N =", nrow(.))) +
geom_point()
}
Note that when wrapping the whole ggplot call in {...} curly braces, you must use the . dot pronoun for the data argument in ggplot(., ...). Then you can call back that object using the . pronoun anywhere in the call.
回答2:
Another option that takes advantage of another of magrittr's pipe-lining features: the tee operator %T>%.
library(ggplot2)
library(magrittr)
# to solidify where the variable will be out-of-scope defined
nr <- "oops"
mtcars %T>%
{ nr <<- nrow(.) } %>%
ggplot(aes(mpg, hp)) +
labs(title=sprintf("N=%i", nr)) +
geom_point()
(This can also be done using dplyr's do({nr <<- nrow(.)}) %>%.)
This differs from Brian's answer in two ways:
Subjectively "cleaner looking", in that the
ggplotcode is not indented within a code block. (As commented, though, the blending of different pipelines could be a negative as well.)It has side-effect, by creating
nroutside of the pipeline and ggplot pipes. By pre-assigningnr, I think this mitigates reaching outside of the local environment, but it's still a little sloppy.
来源:https://stackoverflow.com/questions/45088454/how-do-i-access-the-data-frame-that-has-been-passed-to-ggplot