Reputation: 309
I am relatively new to R. My question results from a project in an online learning course. I am using R studio to make multiple plots from a function call. I want a new plot for each column which represents the y-axis while the x-axis remains equal to the month. The function works when displaying a single variable. However, when I try the function call using multiple columns I receive:
"Error: More than one expression parsed"
Similar code worked in the online program's simulated platform.
I have provided my code below with a small sample from the data frame. Is it possible to derive multiple plots in this way? If so, how can I update or correct my code to make the plot for each column.
month <- c('mar', 'oct', 'oct')
day <- c('fri', 'tue', 'sat')
FFMC <- c(86.2, 90.6, 90.6)
DMC <- c(26.2, 35.4, 43.7)
DC <- c(94.3, 669.1, 686.9)
ISI <- c(5.1, 6.7, 6.7)
temp <- c(8.2, 18.0, 14.6)
RH <- c(51, 33, 33)
wind <- c(6.7, 0.9, 1.3)
rain <- c(0.0, 0.0, 0.0)
forestfires_df <- data.frame(month, day, FFMC, DMC, DC, ISI, temp, RH, wind, rain)
library(ggplot2)
library(purrr)
month_box <- function(x , y) {
ggplot(data = forestfires_df, aes_string(x = month, y = y_var)) +
geom_boxplot() +
theme_bw()
}
month <- names(forestfires_df)[1]
y_var <- names(forestfires_df)[3:10]
month_plots <- map2(month, y_var, month_box)
#After running month_plots I receive "Error: More than one expression parsed"
Upvotes: 1
Views: 634
Reputation: 16842
Like I mentioned in a comment, aes_string
has been soft-deprecated in favor of using tidyeval to write ggplot2
functions. You can rewrite your function as a simple tidyeval-based one, then map over the columns of interest passing bare column names or their positions the way you would with most other tidyverse functions.
There are a couple ways to write a function like this. The older way is with quosures and unquoting columns, but its syntax can be confusing. dplyr
comes with a very in-depth vignette, but I like this blog post as a quick guide.
month_box_quo <- function(x, y) {
x_var <- enquo(x)
y_var <- enquo(y)
ggplot(forestfires_df, aes(x = !!x_var, y = !!y_var)) +
geom_boxplot()
}
A single call looks like this, with bare column names:
month_box_quo(x = month, y = DMC)
Or with map_at
and column positions (or with vars()
):
# mapped over variables of interest; assumes y gets the mapped-over column
map_at(forestfires_df, 3:10, month_box_quo, x = month)
# or with formula shorthand
map_at(forestfires_df, 3:10, ~month_box_quo(x = month, y = .))
The newer tidyeval syntax ({{}}
, or curly-curly) is easier to follow, and returns the same list of plots as above.
month_box_curly <- function(x, y) {
ggplot(forestfires_df, aes(x = {{ x }}, y = {{ y }})) +
geom_boxplot()
}
Upvotes: 0
Reputation: 887108
The issue is that the function arguments should match the ones inside
month_box <- function(x , y) {
ggplot(data = forestfires_df, aes_string(x = x, y = y)) +
geom_boxplot() +
theme_bw()
}
If we use 'month' and 'y_var', 'y_var' is of length 8 and that is the reason we do the looping in map
. With the change, the map2
should work as expected
map2(month, y_var, month_box)
Or using anonymous function
map2(month, y_var, ~ month_box(.x, .y))
Upvotes: 2