I'm preparing a small r-package and I would like to use the function plot()
on an object created through a function, and getting a customized plot. For instance, this is a very silly example function:
myfun <- function(x,y){
A <- B <- c()
for(i in 1:x) {
A[i] <- i^2
B[i] <- i^2+1}
return(list(A,B))
}
Then, I create a list with 2 vectors:
obj <- myfun(5,6)
So, the standard approach to get a plot would be:
plot(x=obj[[1]],y=obj[[2]], main='my title',type = 'b', col='red)
BUT, instead of that, I would like to run the following:
plot(obj)
And get the same. So I don't know how to code that into my function in order to get a completely personalize plot. Also, I would like to get a customized summary table, for instance, running the following:
summary(obj)
Be able to get a table with means, sd, etc. I was looking all over StackOverflow about this, with no success, but maybe I used the wrong keywords. Thanks a lot in advance.
If you give your myfun ouput a custom class:
class(obj) <- 'myClass'
Then add a new s3 method:
plot.myClass <- function(obj) {
plot(x=obj[[1]],y=obj[[2]], main='my title',type = 'b', col='red)
}
Now you can use:
plot(obj)
The answer by SmokeyShakers about plotting is correct, but for your other question about being able to get a table with means, sd, etc. You need to convert your obj to a data frame and then run summary, to be able to get all that stats.
summary(data.frame(x=obj[[1]],y=obj[[2]]))
x y
Min. : 1 Min. : 2
1st Qu.: 4 1st Qu.: 5
Median : 9 Median :10
Mean :11 Mean :12
3rd Qu.:16 3rd Qu.:17
Max. :25 Max. :26
Edit: Or to be consistent, you can do the following:
summary.myClass <- function(obj){summary(data.frame(x=obj[[1]],y=obj[[2]]))}
summary(obj)
You need to define a class and then create your own personal method.
plot()
and summary()
are generic functions. If you type on your console:
methods(plot)
methods(summary)
You will see a lot of methods already do exist.
While if you print plot
on your console you will see that:
plot
#> function (x, y, ...)
#> UseMethod("plot")
#> <bytecode: 0x2363df0>
#> <environment: namespace:graphics>
plot
calls a function called UseMethod
that will look for all the methods available in the namespaces and the global environment related to plot
.
Edit your code this way:
myfun <- function(x,y){
A <- B <- c()
for(i in 1:x) {
A[i] <- i^2
B[i] <- i^2+1}
structure(class = "myclass", list(A,B))
}
This way you can create your class. Your function myfun()
will always return an object myclass
which is a list of two numeric vectors.
Now you can create your own methods. A method should start with the same name of the generic function and be followed by a dot and the name of your class.
plot.myclass <- function(obj, ...){
plot(x = obj[[1]], y = obj[[2]], main='my title', type = 'b', col = 'red', ...)
}
obj <- myfun(5,6)
plot(obj)
Add ...
in case you want to add more features to your plot in the future.
Same stuff for summary
. You can to the same for print
for example.
PS: I would strongly advice you to use a lapply()
, vapply()
or a purrr::map_dbl()
instead of a for
loop on your example. And to go for a neat ggplot
instead of plot.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.