3

I created a lattice scatterplot using xyplot that is grouped into separate categories. Now I am trying to create a single hexplot for each of the categories from the scatterplot. I can hard code the variables but I would prefer to do it in a loop since I would be doing this multiple times which will have new categories.

I started with a table that looks like this

 Name     Category     Value1      Value2
sample1    cat1     10     1.5
sample2    cat2     10     1.5
sample3    cat3     10     1.5
sample4    cat1     10     1.5
sample5    cat1     10     1.5
sample6    cat2     10     1.5
sample7    cat3     10     1.5

I was able to create a list of dataframes using

testing <- split(Mydata, Mydata$Category)

then I can create a plot by

testing2 <- as.data.frame(testing[["cat1"]]) #I keep on needing to change this for each Category that I have
ggplot(testing2, aes(x = testing2[,3], y = testing2[,4])) +
  geom_hex(bins = 30)

testing2 looks like this

 Name     Category     Value1      Value2
sample1    cat1     10     1.5
sample4    cat1     10     1.5
sample5    cat1     10     1.5

I tried

for(i in testing){
  testing3 <- i
  xtra <- ggplot(testing3, aes(x = testing3[,3], y = testing3[,4])) + geom_hex(bins = 30)
  xtra
}

This ends up with xtra being the last dataframe on the list.

Can someone help me with this? I would want to be able to create plots without having to change $Category each time as I have >50 categories for everytime that I want to do this.

--edit1 As per suggestion, I created a function;

myFirstFun <- function(column)
{
  testing2 <- as.data.frame(testing[[column]])
  column <- enquo(column)
  ggplot(testing2, aes_string(x ="Value1", y = "Value2", group = column)) +
    geom_hex(bins = 30)
}

And this;

myFirstFun("cat1")

produces this;

 Name     Category     Value1      Value2
sample1    cat1     10     1.5
sample4    cat1     10     1.5
sample5    cat1     10     1.5

but when I try to use a for loop;

for(i in categorynames){###categorynames is a vector that has all my categorynames
  myFirstFun(i)
}

it will only produce the last graph on the list. How would I do this to produce n number of graphs (n = number of my categories)? Without me manually doing

myFirstFun("cat1")
myFirstFun("cat2")
myFirstFun("cat3")
...
  • 1
    please show some reproducible data using `dput(my_data)` – Roman Apr 04 '19 at 15:28
  • Hard to tell with info as given, but ifi it's a question about variables in `aes()` mappings, this is probably the R-FAQ duplicate: https://stackoverflow.com/questions/22309285/how-to-use-a-variable-to-specify-column-name-in-ggplot – Gregor Thomas Apr 04 '19 at 15:29
  • 2
    @Gregor worth noting that both `aes_string` and `aes_` will work but are being/have been deprecated in favor of tidyeval – camille Apr 04 '19 at 15:48
  • Possible duplicate of [How to use a variable to specify column name in ggplot](https://stackoverflow.com/questions/22309285/how-to-use-a-variable-to-specify-column-name-in-ggplot) – camille Apr 04 '19 at 15:48
  • @Gregor I turned the code now into function but my problem still persist as I cannot loop thru a list to create multiple different plots. ```myFirstFun <- function(column) { testing2 <- as.data.frame(testing[[column]]) column <- enquo(column) ggplot(testing2, aes_string(x ="Value1", y = "Value2", group = column)) + geom_hex(bins = 30) }``` I can create a plot but when I try to do a loop using ```for(i in categorynames){ myFirstFun(i) }``` I still end up with only being able to plot the last category in the list. categorynames is a vector that has all my category names – Juan Paolo Sicat Apr 04 '19 at 16:23
  • @camille see comment above – Juan Paolo Sicat Apr 04 '19 at 16:24
  • Please [edit] your question to include code. It's hard to read in comments – camille Apr 04 '19 at 16:28
  • @camille Sorry. edited the question now. – Juan Paolo Sicat Apr 04 '19 at 17:09

1 Answers1

2

You can built a function in which you use dplyr::filter to select the desired Category then do the plotting.

To loop through every Category, use purrr::map and store all results in a list. From there you can either print the plot of your choice or merge them all together in 1 page or multiple pages

library(tidyverse)

df <- read.table(text = "Name     Category     Value1      Value2
sample1    cat1     11     2.5
sample2    cat2     13     1.5
sample3    cat3     12     3.5
sample4    cat1     15     6.5
sample5    cat1     17     4.5
sample6    cat2     14     7.5
sample7    cat3     16     1.5",
                 header = TRUE, stringsAsFactors = FALSE)

cat_chart1 <- function(data, category){

  df <- data %>% 
    filter(Category == category)

  plot1 <- ggplot(df, aes(x = Value1, y = Value2)) + 
    geom_hex(bins = 30)

  return(plot1)
}

# loop through all Categories
plot_list <- map(unique(df$Category), ~ cat_chart1(df, .x)) 
plot_list[[1]]                 

# combine all plots
library(cowplot)
plot_grid(plotlist = plot_list, ncol = 2)

Created on 2019-04-04 by the reprex package (v0.2.1.9000)

Tung
  • 26,371
  • 7
  • 91
  • 115