如何自定义属于包的 R 函数内的图?

How customize a plot inside a R function which belong to a package?

我正在准备一个小的 r 包,我想在通过函数创建的对象上使用函数 plot(),并获得自定义绘图。例如,这是一个非常愚蠢的示例函数:

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

然后,我创建了一个包含 2 个向量的列表:

obj <- myfun(5,6)

因此,获得绘图的标准方法是:

plot(x=obj[[1]],y=obj[[2]], main='my title',type = 'b', col='red)

但是,我想运行以下内容:

plot(obj)

并得到相同的。所以我不知道如何将其编码到我的函数中以获得完全个性化的情节。另外,我想获得自定义摘要 table,例如 运行 如下:

summary(obj)

能够通过means、sd等获得table。 我在 Whosebug 上到处寻找这个,但没有成功,但也许我使用了错误的关键字。提前致谢。

如果你给你的 myfun 输出自定义 class:

class(obj) <- 'myClass'

然后添加一个新的s3方法:

plot.myClass <- function(obj) {
      plot(x=obj[[1]],y=obj[[2]], main='my title',type = 'b', col='red)
}

现在您可以使用:

plot(obj)

SmokeyShakers 关于密谋的回答是正确的,但是对于你关于能够通过 means、sd 等获得 table 的其他问题。 您需要将 obj 转换为数据框,然后 运行 摘要,才能获得所有统计数据。

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  

编辑:或者为了保持一致,您可以执行以下操作:

summary.myClass <- function(obj){summary(data.frame(x=obj[[1]],y=obj[[2]]))}
summary(obj)

您需要定义一个class,然后创建您自己的个人方法。

plot()summary() 是泛型函数。如果您在控制台上键入:

methods(plot)
methods(summary)

您会看到很多方法已经存在。

而如果您在控制台上打印 plot,您将看到:

 plot
 #> function (x, y, ...) 
 #> UseMethod("plot")
 #> <bytecode: 0x2363df0>
 #> <environment: namespace:graphics>

plot 调用一个名为 UseMethod 的函数,该函数将查找与 plot.

相关的命名空间和全局环境中的所有可用方法

以这种方式编辑您的代码:

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

  }

这样您就可以创建您的 class。您的函数 myfun() 将始终 return 一个对象 myclass,它是两个数字向量的列表。

现在您可以创建自己的方法了。方法应以与通用函数相同的名称开头,后跟一个点和您的 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)

添加 ... 以防您将来想为您的地块添加更多功能。

summary 的内容相同。例如,您可以对 print 使用相同的方法。

PS:我强烈建议您在示例中使用 lapply()vapply()purrr::map_dbl() 而不是 for 循环。 并寻求一个整洁的 ggplot 而不是情节。