1

I am trying to map/loop over the species column in the Iris data set to create a plot for each species. The below script returns three charts but all have the same data plotted and are not divided by species. The map function appears to ignore the species_list and just looks at the entire dataframe. Been trying a varying approached but can't get any to work. Any help greatly appreciated

Cheers

library(ggplot2) 
library(purrr) 

species_list = unique(Iris$Species)

species_plot = function(x,y) {

     ggplot(data = Iris,colour = Species, aes_string(x=x,y=y)) + 
     geom_point(shape = 21, aes(fill = Species),colour = "black", size =8)

 }


species_bins = map(species_list, ~species_plot("sepal_length", "sepal_width") )
berwyn72
  • 45
  • 6

2 Answers2

2

Try this:

# Load packages
library(tidyverse)
library(rlang)

# Define the function
species_plot <- function(x, y, pal = c('#2678B2', '#FD7F28', '#339F34')) {

    # Set variables to plot using the black magic of rlang
    x_var <- enquo(x)
    y_var <- enquo(y)

    # Generate plots
    iris_plots <- iris %>% 
        # Group and nest data by Species 
        # Creates a dataframe with two columns: 'Species' and 'data' (a list-column)
        group_by(Species) %>% 
        nest() %>% 
        # Add a new column with the ggplot objects
        mutate(plots = pmap(.l = list(data, pal, as.character(Species)), 
                            ~ ggplot(data = ..1) + # first element of .l
                                aes(x = !!x_var, # expose the x and y variables
                                    y = !!y_var) +
                                geom_point(shape = 21,
                                           size = 8,
                                           fill = ..2, # second element of .l
                                           colour = '#000000') +
                                labs(title = str_to_title(str_glue('{..3}'))) + # third element of .l
                                theme_bw() +
                                theme(legend.position = 'none')))

    # Walk through the plots column, printing each ggplot object
    walk(.x = iris_plots$plots,
         ~ print(.x))
}

# Test the function
species_plot(x = Sepal.Length, y = Sepal.Width)

Created on 2018-09-13 by the reprex package (v0.2.0).

Peter K
  • 706
  • 5
  • 8
1

We can change the function to include 'species_list'

species_list <- unique(iris$Species)
species_plot <- function(x,y, z) {

  ggplot(data = iris, aes_string(x=x,y=y, colour = z)) + 
     geom_point(shape = 21, aes_string(fill = z),
               colour = "black", size =8)

  }

map(species_list, ~species_plot("Sepal.Length", "Sepal.Width", .x) )
akrun
  • 874,273
  • 37
  • 540
  • 662
  • 1
    Hi many thanks for the reply and you time, bit i still cannot get what i need. The code gives me three charts but with all species plotted on each one, what i am after achieving is a separate plot for each species. – berwyn72 Sep 13 '18 at 16:09
  • berwyn72: I think you're mistaken because @akrun's answer provides 3 separate graphs with one species per graph – hackR Sep 13 '18 at 16:47