如何使用用户的按钮输入来修改RShiny中的全局变量?

问题描述 投票:0回答:1

最近我在下面的示例中进行了很多努力。在其最基本的格式中,我有一个按钮some_button和一个输出result。当用户与平台交互时,我的意图是运行曲线拟合方法(来自minpack.lm包),并使用曲线拟合方法输出的四个参数来初始化Convert()函数。为了实现这一点,我的想法是初始化一个空的用于存储系数(curvefit_coeff)的反应变量和一个空的Convert()函数。然后,我将observeEventonce参数设置为TRUE,以确保其仅运行一次。因此,我认为这一次运行应同时初始化我的curvefit_coeff和我的Convert()函数。但是,我似乎无法从observeEvent中“取出”这些值。我尝试使用输出winDialog以及我的result文本输出,但是我总是以以下错误消息结尾:

Error in .getReactiveEnvironment()$currentContext() : 
  Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)
library(shiny)
library(minpack.lm)

ui <- fluidPage(
  actionButton("some_button", "Press me!"),
  textOutput("result")
)


server <- function(input, output, session) {

  # I tried to initialize my two variables in question as globals within the server function
  curvefit_coeff <- reactive({ })
  Convert <- function(x) { }

  # This function fits a curve and returns the four parameters of the fitted curve
  CurveFit <- function(pp) {
    ds <- data.frame("x" = c(0.01, pp, 999, 1000), "y" = c(0, 0.5, 0.999, 1))

    nlmInitial <- list(a = 0.5, power1 = -1, b = -1, power2 = 0.5)
    m <- nlsLM(y ~ a*I(x^power1) + b*I(x^power2),
               data = ds,
               start = nlmInitial,
               trace = F,
               control = nls.lm.control(maxiter = 1024))

    summary(m)$coefficients[,1]
  }

  # At the very first time the button is pressed, do the curve fit and using the parameters 
  # from the curve fit, initialize the Convert() function that will be used later on
  observeEvent(input$some_button, {

    winDialog("ok", message = "Button pressed!")

    curvefit_coeff <- reactive({ CurveFit(pp = 50) })

    Convert  <- function(x) {
      (curvefit_coeff()[1])*x^(curvefit_coeff()[2]) + (curvefit_coeff()[3])*x^(curvefit_coeff()[4])
    } 

  },ignoreInit = FALSE, once = TRUE)


  # When I try to access either the coefficients from the curve fit or the Convert() 
  # function itself, I get an error:
  output$result <- curvefit_coeff()
  output$result <- Convert(3)

}

shinyApp(ui, server)
r shiny global-variables
1个回答
1
投票

好,这里发生了一些事情。首先,如果要在输出中显示两个内容,则应具有两个不同的输出变量。接下来,错误消息来自于您直接将向量分配给输出变量。当您想要显示通常在控制台中运行时看到的内容时,应将renderPrinttextOutput结合使用。如果您进行处理并具有类似cat的输出,则需要改用renderText。最后,您不想在reactive中用赋值运算符(<-)重新定义observeEvent值-您只想更新该值(赋值运算符未完成)。我的建议是使用reactiveValues来跟踪这组操作所需的一切,并输出如下。

library(shiny)
library(minpack.lm)

ui <- fluidPage(
  actionButton("some_button", "Press me!"),
  textOutput("result1"),
  textOutput("result2")
)


server <- function(input, output, session) {

  # I tried to initialize my two variables in question as globals within the server function
  curve_fit <- reactiveValues(coeffs = NA,
                              Convert = function(x) return(NA))

  # This function fits a curve and returns the four parameters of the fitted curve
  CurveFit <- function(pp) {
    ds <- data.frame("x" = c(0.01, pp, 999, 1000), "y" = c(0, 0.5, 0.999, 1))

    nlmInitial <- list(a = 0.5, power1 = -1, b = -1, power2 = 0.5)
    m <- nlsLM(y ~ a*I(x^power1) + b*I(x^power2),
               data = ds,
               start = nlmInitial,
               trace = F,
               control = nls.lm.control(maxiter = 1024))

    summary(m)$coefficients[,1]
  }

  # At the very first time the button is pressed, do the curve fit and using the parameters 
  # from the curve fit, initialize the Convert() function that will be used later on
  observeEvent(input$some_button, {
    curve_fit[['coeffs']] <- CurveFit(pp = 50)
  })

  observeEvent(curve_fit[['coeffs']], {
    curve_fit[['Convert']]  <- function(x) {
      (curve_fit[['coeffs']][1])*x^(curve_fit[['coeffs']][2]) + (curve_fit[['coeffs']][3])*x^(curve_fit[['coeffs']][4])
    }
  })


  # When I try to access either the coefficients from the curve fit or the Convert() 
  # function itself, I get an error:
  output$result1 <- renderPrint({
    if(all(is.na(curve_fit[['coeffs']]))) return('Button not pressed.')
    curve_fit[['coeffs']]
    })
  output$result2 <- renderPrint({
    if(is.na(curve_fit$Convert(3))) return('Button not pressed.')
    curve_fit$Convert(3)
    })

}

shinyApp(ui, server)
静态R Markdown文档中不支持闪亮的应用程序

reprex package(v0.3.0)在2019-10-06创建

© www.soinside.com 2019 - 2024. All rights reserved.