3

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:

enter image description here

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.

owl
  • 1,841
  • 6
  • 20
  • 30
  • 1
    It seems like `substitute()` doesnt get variables. As a sidenote, shouldn't `pet name` be obtained using something like `as.character(pet.stats$name[i]))`? Else you give a vector with all the levels. – boski Sep 12 '19 at 09:59
  • 1
    also check https://stackoverflow.com/questions/16659096/italics-in-title-of-lattice-graph – boski Sep 12 '19 at 10:13
  • Thanks for the URL. I did not see this one before I posted it. – owl Sep 12 '19 at 20:14

1 Answers1

2

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)
}

MDEWITT
  • 2,338
  • 2
  • 12
  • 23
  • Thank you, this worked and gave me exactly what I wanted! I will check env variable I was not aware of here (https://www.rdocumentation.org/packages/base/versions/3.6.1/topics/substitute). – owl Sep 12 '19 at 20:16