I'm trying to plot from a rather complex array in R. I want to produce an image with 3 by 3 graphs, each with red and blue points on it.
I've got a structure of apply loops which works, but I'd like to change the y maximum value by each row.
I would normally do this using a counter, like i, in other languages. But the apply thing in R is completely baffling me!
par(mfrow=c(3,3),pty="s")             # a 3 by 3 graphic
set.seed(1001)
x <- 1:54                             # with 1 to 54 along the x axis
y <- array(rexp(20), dim=c(54,6,3,2)) # and the y axis coming 
                                      # from an array with dimensions as shown.
ymax <- c(1,0.1,0.3)                  # three different y maximum values I want 
                                      # on the graphic, one for each row of graphs
counter <- 1                          # a counter, starting at 1, 
                                      # as I would use in a traditional loop
apply(y[,3:5,,], 2, function(i)       # my first apply, which only considers
                                      # the 3rd, 4th and 5th columns
    {
    yy <- ymax[counter]               # using the counter to select my ylimit maximum
    apply(i, 2, function (ii)         # my second apply, considering the 3rd 
                                      # dimension of y
        {
            plot(x,ii[,1], col="blue", ylim=c(0,yy)) 
                                      # plotting the 4th dimension
                points(x,ii[,2], col="red") 
                                      # adding points in a different 
                                      # colour from the 4th dim. 
    })
})
Thank you in advance for your thoughts, they are very much appreciated!
Cheers Kate
I think it might be easier to use loops in this case.
Also, your code does not have a line to update the counter, like counter <- counter + 1. From inside apply you will need to assign to the global environment using <<-, note the doubled smaller < sign. An example using lapply, e.g.
Single lapply usage
counter <- 0
lapply(1:3, function(x) {
  counter <<- counter + 1
  cat("outer", counter, "\n")
  plot(1:10, main=counter)
})
Or nested usage of lapply
counter <- 0
lapply(1:3, function(x) {
  counter <<- counter + 1
  cat("outer", counter, "\n")
  lapply(1:3, function(x) {
    counter <<- counter + 1
    cat("inner", counter, "\n") 
    plot(1:10, main=counter)     
  })
})
                        The key thing here is to use lapply on the index rather than on the array itself, so then you can use the index to subset both your y limits and the array ahead of the inner loop.  This also avoids having to use the <<- construct.
Simplified your data a bit:
par(mfrow=c(3,3),pty="s")             # a 3 by 3 graphic
set.seed(1001)
x <- 1:10                             # with 1 to 54 along the x axis
dims <- c(10,6,3,2)
y <- array(rexp(prod(dims)), dim=c(10,6,3,2)) # and the y axis coming 
ymax <- c(1,0.1,0.3)
lapply(1:3, function(counter, arr) {
  apply(
    arr[ ,counter + 2, , ], 2, 
    function(ii) {
      plot(x, ii[,1], col="blue", ylim=c(0,ymax[counter]))
      points(x, ii[,2], col="red") 
    } )
  },
  arr=y
)

I am not going to rewrite your code as I must say it is difficult to comprehend, but this will help: you can update a variable outside of the scope of apply by using <<- assignment, e.g. to update some external "counter"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With