Reputation: 608
I have a dataframe df
in R. (We can use the example of iris
.) I also have simple transformations of iris:
iris0 <- iris
iris1 <- cbind(log(iris[,1:4]),iris[5])
iris2 <- cbind(sqrt(iris[,1:4]),iris[5])
I want to create a list object containing the density distributions of all numerical attributes in iris
, for each of these three datasets. (So, in total 4 attributes for each of 3 datasets: 12 density plots in one list object.) I would like the densities from a given dataset (for each attribute) to all be a single colour, i.e. the colour should depend purely on the dataset. Using just base R, I thought Map would be the best way to do it:
datasets=c("iris0","iris1","iris2")
Map(function(.x, .y, df) {
ggplot(data = get(df), aes(x=.x)) +
geom_density(aes(fill=df)) + xlab(.y) + ggtitle(label=paste0(.y," Density in ",df," dataset"))}, df[names(df)], names(df), as.character(datasets) )
This seems to run into an error, Error in get(df) : object 'df' not found
. I also tried wrapping the df[names(df)]
and names(df)
with get
around each df
, but the error persisted.
I can also see other potential problems down the line--I'm not sure fill=df
will correctly encode the data-frames as a factor and ensure they are a separate unique colour each (but each remain the same colour for all attributes).
Can anyone help solve this one?
(I would like to do it without using any packages besides base R + ggplot2 and potentially dplyr)
Upvotes: 1
Views: 264
Reputation: 125797
Instead of using Map
I make use of lapply
to first iterate over the datasets
and second over the variables via names(get(df))[1:4]
At the end I flatten the list of lists using Reduce
. I also added a custom palette to fill the density plots by dataset. Try this:
iris0 <- iris
iris1 <- cbind(log(iris[,1:4]),iris[5])
iris2 <- cbind(sqrt(iris[,1:4]),iris[5])
datasets <- c("iris0","iris1","iris2")
palfill <- c("iris0" = "red","iris1" = "green","iris2" = "blue")
library(ggplot2)
# list of lists
plots <- lapply(datasets, function(df) {
lapply(names(get(df))[1:4], function(.x) {
ggplot(data = get(df), aes_string(x = .x)) +
geom_density(aes(fill = df)) +
scale_fill_manual(values = palfill) +
xlab(.x) +
ggtitle(label = paste0(.x, " Density in ", df," dataset"))
})
})
# flatten
plots <- Reduce(c, plots)
plots[[1]]
Created on 2020-05-16 by the reprex package (v0.3.0)
Upvotes: 1