使用Shiny,R和期货的外部类

Hes*_*ons 8 future r shiny

我正在尝试整合一个框架,让Shiny在我拥有的一组类上异步工作,使用期货和可能的承诺.我使用一组模拟我的实际设置的外部模块组建了一个测试项目.

注意:我还试图实现在此框架中抛出错误的完全相同的调用:FutureProcessor.R,并且返回的错误是相同的.

基本上,按钮单击调用实例化类的实例的函数,然后执行简单的计算.当第一个按钮作为一个直接过程运行时,这很好.但是,当我使用%< - %assigmment运行它时,它返回以下错误:Warning: Error in getClass: "cTest" is not a defined class

我很清楚,我没有做到这一点!但是我不确定我想做的事情是否可能?

设置如下:

闪亮的应用程序:

## Load required libraries
pacman::p_load(shiny, here, promises, future)

setwd(here())
source(here("testing.R"))
source(here("TestClass.R"))
plan(multisession)

# Define UI
ui <- fluidPage(

   # Application title
   titlePanel("Test external classes"),

   # Sidebar 
   sidebarLayout(
      sidebarPanel(
         actionButton("clickMe", "I work"),
         actionButton("clickMeToo", "I don't work")
      ),

      # Show a text output
      mainPanel(
         verbatimTextOutput("outputText1"),
         verbatimTextOutput("outputText2")
      )
   )
)

# Define server logic 
server <- function(input, output) {

  myResult <- NULL

   observeEvent(input$clickMe, {

     ## This works:
      myResult <<- testFutures()
      output$outputText1 <- renderText({paste0("test: ", myResult$Item3)})

   })
   observeEvent(input$clickMeToo, {
     ## This works not:
     myResult %<-% {testFutures()}
     output$outputText2 <- renderText({paste0("test: ", myResult$Item3)})
   })
}

# Run the application 
shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)

我的考试班:

cTest <- setRefClass("cTest", 
                                     fields=list(

                                       Item1="numeric",
                                       Item2="numeric",
                                       Item3= "numeric"),

                                     methods = list(
                                       Reset = function() {
                                         Item1 <<- 0
                                         Item2 <<- 0
                                         Item3 <<- 0
                                       },
                                       AddUp = function() {
                                         Item3 <<- Item1 + Item2
                                       }
                                     )
Run Code Online (Sandbox Code Playgroud)

我的测试功能:

testFutures <- function() {
  output <- new ("cTest")
  output$Reset()
  output$Item1 <- 3
  output$Item2 <- 4
  output$AddUp()
  return(output)
}
Run Code Online (Sandbox Code Playgroud)

gre*_*g L 5

我认为在异步期货中使用引用类存在一些问题,如"未来的R:解决方案的常见问题"中所述.

第一个是缺少全局变量.未来在运行之前会静态检查代码,以确定需要向R进程公开的全局变量.使用时实例化引用类对象时new("classname"),直到运行时(getClass()调用时)才知道实际的类定义,因此将来不会知道导出它.

一个最小的例子:

library(future)

plan(multisession)

RefClassTest <- setRefClass("RefClassTest",
  fields = list(x = "numeric"),
  methods = list(get = function() x)
)

result %<-% new("RefClassTest")
result
## Error in getClass(Class, where = topenv(parent.frame())) :
##   "RefClassTest" is not a defined class
Run Code Online (Sandbox Code Playgroud)

解决方法是使用类生成器实例化RefClassTest$new().但是,现在你遇到导出生成器的问题,因为(我猜)它在内部使用外部指针.对象构造得不正确.

options(future.globals.onReference = "warning")

result %<-% RefClassTest$new()
## Warning message:
##   In FALSE :
##   Detected a non-exportable reference (‘externalptr’) in one of the globals (‘RefClassTest’ of class ‘refObjectGenerator’) used in the future expression

result
## Prototypical reference class object

result$get()
## Error in result$get() : object 'x' not found
Run Code Online (Sandbox Code Playgroud)

我不太了解参考类来解决这两个问题,所以我建议改用R6类.它们在将来的表达式中似乎与引用类没有相同的问题.

R6Test <- R6::R6Class("R6Test",
  public = list(
    x = numeric(0),
    get = function() self$x
  )
)

result %<-% {
  R6Test$new()
}

result
## <R6Test>
##   Public:
##   clone: function (deep = FALSE)
##     get: function ()
##       x:

result$get()
## numeric(0)
Run Code Online (Sandbox Code Playgroud)