簡體   English   中英

對 R 包中的函數進行分組

[英]Grouping functions from an R package

語境

我正在開發一個 R 包,其中包含分為 10 個不同主題的 100 多頁長的函數。

期望的行為

我希望用戶在調用函數時能夠考慮到這些主題。

例如,用戶不必調用foo() ,而是必須執行以下任一操作

load(theme1) # or whatever would be used to load a subgroup of functions
foo()

或類似的東西

theme1$foo()

我要防止用戶做的是直接加載包並調用函數而不考慮主題,即library(package); foo() library(package); foo()

我試過的

我已經使用模塊包來完成前一個包中的后一個解決方案,但是這次由於我的函數是如何相互依賴的,該包的已發布版本不能很好地工作(我已經打開了一個關於該主題的GitHub 問題) )。

我還考慮過編寫自己的解決方案,也許是一些簡單的事情,涉及創建一個sublibrary()函數,該函數一次僅導出幾個函數,但我對此sublibrary()

當然,我猜發布 10 個不同的包在技術上也是可行的,但我認為這太笨拙了,無法考慮。

除了使用模塊之外,有沒有辦法實現上述任一功能?

這里可以使用面向對象的編程,其中theme1是一個類或一個從類實例化的對象,與它相關的函數是方法。 這里有許多替代方案,包括 R 參考類(通過?ReferenceClasses更多信息)、 R6 包proto 包R.oo 包和函數范圍(通過demo("scoping")更多信息demo("scoping")

例如使用 proto 包:

library(proto)

theme1 <- proto(
  foo = function(.) print("foo"),
  bar = function(.) print("bar")
)

theme1$foo()
## [1] "foo"
theme1$bar()
## [1] "bar"

如果這只是一個分組問題,並且如果您不需要本地存儲或繼承,那么我們甚至可以使用列表:

theme1 <- list(foo = function() print("foo"),
               bar = function() print("bar"))

theme1$foo()
## [1] "foo"
theme1$bar()
## [1] "bar"

可以使用許多其他 OO 方法,但它們涉及創建一個類,然后使用該類創建單個對象(這是一個額外的步驟); 但是,它們確實支持問題的 $ 語法。

使用 R6 我們有:

library(R6)

Theme1 = R6Class("theme1",
  public = list(
    foo = function() print("foo"),
    bar = function() print("bar")
  )
)

theme1 <- Theme1$new() # generate a Theme1 object

theme1$foo()
## [1] "foo"
theme1$bar()
## [1] "bar"

或使用參考類(不需要包):

setRefClass(
  "Theme1",
  methods = list(
    foo = function() print("foo"),
    bar = function() print("bar")
  )
)

theme1 <- Theme1()  # generate Theme1 object

theme1$foo()
## [1] "foo"
theme1$bar()
## [1] "bar"

或使用函數作用域(不需要包):

Theme1 <- function() list(
  foo = function() print("foo"),
  bar = function() print("bar")
)

theme1 <- Theme1()

theme1$foo()
## [1] "foo"
theme1$bar()
## [1] "bar"

這是如何實現子sublibrary功能的想法。 在這種情況下,我們將使用它來加載ggplot2一小部分

sublibrary <- function(theme) {
  subgroups <- 
    list(basic   = list(ggplot = ggplot2::ggplot,
                        aes = ggplot2::aes,
                        geom_line = ggplot2::geom_line,
                        geom_point = ggplot2::geom_point),
        advanced = list(scale_color_manual = ggplot2::scale_color_manual,
                        theme = ggplot2::theme))
  
  attach(list2env(subgroups[[theme]]))
}

這意味着我可以在不加載整個包的情況下執行以下操作:

sublibrary("basic")

ggplot(iris, aes(Sepal.Length, Petal.Length, color = Species)) +
  geom_point()

實際上, subgroup對象將存儲在函數外部、包命名空間內的列表或環境中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM