I am trying to change title of each subplot using loop in R. I know there is a similar question here but I was not able to apply this in my case. Here are my data and codes:
# Pet size data and their names
color <- c('W', 'B', 'G', 'W', 'B', 'G', 'W', 'B', 'G', 'W', 'B', 'G', 'W', 'B', 'G', 'W', 'B', 'G')
mass <- c(10, 14, 20, 11, 16, 13, 11, 15, 10, 14, 23, 18, 12, 22, 20, 13, 14, 17)
name <- c('B', 'B', 'B', 'F', 'F', 'F', 'D', 'D', 'D', 'A', 'A', 'A', 'C', 'C', 'C', 'E', 'E', 'E')
# Make it into data frame
pet.stats <- data.frame(color, mass, name)
# Name of pets (I want to plot them by type of pets)
kitty <- c('A', 'B', 'C')
bunny <- c('D', 'E', 'F')
all.pets <- append(kitty, bunny)
all.pets <- as.factor(all.pets)
par(mfrow = c(2, 3), mar = c(4, 4, 2, 1), oma = c(0.5, 0.5, 0.5, 0.5), mgp = c(2.2, 0.7, 0))
# Loop through pet names and give title with pet type and pet name for each subplot
for (i in 1: nlevels(pet.stats$name)) {
barplot(pet.stats$mass[pet.stats$name == levels(pet.stats$name)[i]],
main = substitute(paste('Size of ', bold('lovely'),
ifelse(pet.stats$name[i] %in% kitty, 'kitty', 'bunny'),
' (', levels(pet.stats$name[i]), ')')),
xlab = 'Color', ylab = 'Mass', names = c('White', 'Black', 'Gray'))
abline(h = 0)
}
and this is what I get:
I want each subplot to have a title "Size of lovely (pet type) (pet name)" such as "Size of lovely bunny 'D'"
Could somebody please help fix what I am doing wrong? Thank you.
Ok, so here is you solution. The problem was with R and non-standard evaluation. The substitute
function was freezing the evaluation of functions. The way to get the desired behaviour, is to specify in the env
variable what you need to have evaluated.
Note, I broke out each of the variables and then constructed them in the main
. This makes it a little easier to see what is happening.
# Pet size data and their names
color <- c('W', 'B', 'G', 'W', 'B', 'G',
'W', 'B', 'G', 'W', 'B', 'G',
'W', 'B', 'G', 'W', 'B', 'G')
mass <- c(10, 14, 20, 11, 16, 13, 11, 15,
10, 14, 23, 18, 12, 22, 20, 13, 14, 17)
name <- c('B', 'B', 'B', 'F', 'F', 'F', 'D',
'D', 'D', 'A', 'A', 'A', 'C', 'C',
'C', 'E', 'E', 'E')
# Make it into data frame
pet.stats <- data.frame(color, mass, name)
# Name of pets (I want to plot them by type of pets)
kitty <- c('A', 'B', 'C')
bunny <- c('D', 'E', 'F')
all.pets <- append(kitty, bunny)
all.pets <- as.factor(all.pets)
Now note the list of variables passed to substitute
par(mfrow = c(2, 3), mar = c(4, 4, 2, 1), oma = c(0.5, 0.5, 0.5, 0.5), mgp = c(2.2, 0.7, 0))
# Loop through pet names and give title with pet type and pet name for each subplot
for (i in 1: nlevels(pet.stats$name)) {
# Break out the names
animal_type <- ifelse(pet.stats$name[i] %in% kitty, 'kitty', 'bunny')
animal_names <- levels(pet.stats$name)[i]
barplot(pet.stats$mass[pet.stats$name == levels(pet.stats$name)[i]],
main = substitute(paste('Size of ', bold('lovely'),
animal_type,
' (', animal_names, ')'),
env = list(animal_type = animal_type,
animal_names = animal_names)),
xlab = 'Color', ylab = 'Mass', names = c('White', 'Black', 'Gray'))
abline(h = 0)
}