Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change titles for each subplot using loop in R

Tags:

loops

plot

r

title

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.

like image 950
owl Avatar asked May 17 '26 01:05

owl


1 Answers

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

like image 109
MDEWITT Avatar answered May 20 '26 00:05

MDEWITT



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!