Search code examples
rsapply

R: How to carry over colnames attribute using sapply?


The following toy code yields a density plot for each column of the y dataframe. However, sapply does not carry over the column name attributes. I'd like to name each new plot with the column name from which the data comes from. Any help is appreciated!

y <- data.frame(sample(1:50), sample(1:50), sample(1:50))
colnames(y) <- c("col1", "col2", "col3")

toy.func <- function(y) {
  X11()
  plot = plot(density(y), main = colnames(y))
  return(plot)
}

result <- sapply(y, toy.func)

Solution

  • You are right and it makes sense: y is seen as a list and sapply goes over its element that are vectors, and we cannot assign a name to a vector. So, a somewhat minimal deviation from your approach that achieves what you want would be to use mapply:

    toy.func <- function(y, name) {
      X11()
      plot = plot(density(y), main = name)
      return(plot)
    }
    mapply(toy.func, y, colnames(y))
    

    It applies toy.func by taking one element from y and one from colnames(y) in every step.


    Another option would be to go over the column names at the same time providing the data frame

    toy.func <- function(name, data) {
      X11()
      plot = plot(density(data[, name]), main = name)
      return(plot)
    }
    sapply(colnames(y), toy.func, y)
    

    Also note that your function can be simplified to, in this case,

    toy.func <- function(name, data) {
      X11()
      plot(density(data[, name]), main = name)
    }