Reputation: 2900
So I have been trying to make an S3 generic plotting function in R... I have read several blogs and examples explaining S3 functions... but I'm still having trouble figuring this out. In my package I have a function that creates a matrix. Then, I also have another function that takes the created matrix as an argument and then plots this matrix as a heat-map. I am trying to turn this second function (i.e., plotting heat-map) into an S3 generic function. The example below will hopefully explain what I mean.
To begin I have a function to create a matrix:
#' myMatrix
#'
#' @description Creates Matrix
#'
#' @param rows No of rows
#' @param cols No of cols
#'
#' @importFrom stats "runif"
#'
#' @export
myMatrix <- function(rows = 10, cols = 10){
n <- rows # no or rows
p <- cols # no of cols
# Create matrix of values
myMat <- matrix(runif(n*p, 0, 1), nrow=n) # Create matrix
colnames(myMat) <- paste0("x", 1:p) # Name columns
rownames(myMat) <- paste0("x", 1:p) # Name rows
return(myMat)
}
I would then store the result of the matrix like so:
mat <- myMatrix(10,10)
Then, in a separate script, I was trying to create the S3 generic plotting function, like so:
#' heatMapTEST
#'
#' @description Plots plot
#'
#' @param myMat Given Matrix
#'
#' @importFrom ggplot2 "ggplot"
#'
#' @export
heatMapTEST <- function(myMat){
UseMethod('plot')}
#' @export
plot.heatMapTEST <- function(myMat){
df <- reshape2::melt(myMat, c("x", "y"), value.name = "z")
head(df)
ggplot(data=df,aes(x=x,y=y,fill=z))+
geom_tile()
}
And then (I guess) I would call it like so:
plot(heatMapTEST(mat))
But this throws back an error saying:
Error in h(simpleError(msg, call)) : error in evaluating the argument 'x' in selecting a method for function 'plot': no applicable method for 'plot' applied to an object of class "c('matrix', 'array', 'double', 'numeric')"
I'm very new to writing S3 methods, so really I have no idea if I'm even partially correct in how im doing this... any suggestions as to how I would create a generic S3 to allow me to use the heatMapTEST
function with the generic plot
function?
Upvotes: 0
Views: 811
Reputation: 206606
The S3 methods work when you add classes to your objects. If you want your matrix to have a special plotting method, then you just need to add a class to it. Observe
myMatrix <- function(rows = 10, cols = 10){
n <- rows # no or rows
p <- cols # no of cols
# Create matrix of values
myMat <- matrix(runif(n*p, 0, 1), nrow=n) # Create matrix
colnames(myMat) <- paste0("x", 1:p) # Name columns
rownames(myMat) <- paste0("x", 1:p) # Name rows
class(myMat) <- c("heatMapTEST", class(myMat))
return(myMat)
}
class(myMatrix(10, 10))
# [1] "heatMapTEST" "matrix" "array"
So this function now has the class "heatMapTEST" but it will also behave like a matrix is no special methods for that class exist. When you call plot()
, it will look to match the first class it can. You can see all the existing generic plot methods with methods(plot)
. You can create your own just as you did above
plot.heatMapTEST <- function(myMat){
df <- reshape2::melt(myMat, c("x", "y"), value.name = "z")
head(df)
ggplot(data=df,aes(x=x,y=y,fill=z))+
geom_tile()
}
and you would just call plot()
on the object returned from myMatrix
to get your plot
plot(myMatrix(10,10))
Upvotes: 4