【问题标题】:Using numeric value inside of reactive context in a shiny app在闪亮的应用程序中使用反应上下文中的数值
【发布时间】:2020-06-13 10:32:54
【问题描述】:

我刚开始研究闪亮的应用程序,所以这很可能是一个非常基本的问题,但是在搜索论坛后我仍然无法得到它。

作为我的第一个应用程序的一部分,我有一个精确的 100000 个案例的模拟群体,我想使用 for 循环从中抽取 n 个随机样本。 所以一般的代码是这样的:

samples<-list(NULL)
for(i in 1:100){samples[[i]]<-dplyr::sample_n(population, size=200, replace=FALSE)}

现在我想包含一个滑块,它替换 for 循环中的 100,以便用户可以决定要绘制多少个样本。 但是,当在 UI 中定义滑块然后在服务器端尝试以下操作时

samples<-list(NULL)
for(i in 1:input$n_samples){samples[[i]]<-dplyr::sample_n(population, size=200, replace=FALSE)} 

我收到以下错误:

.getReactiveEnvironment()$currentContext() 中的错误:操作不 允许没有活动的反应上下文。 (你试图做某事 这只能从反应式表达式或观察者内部完成。)

接下来我试过了

samples <- reactive({   
samples<-list(NULL)
for(i in 1:input$n_samples){samples[[i]]<-dplyr::sample_n(population, size=200, replace=FALSE)}     
})  

以及带有 reactiveVal()、reactiveValues() 和各种变体但没有成功的版本。

所以基本上,我想要的是用户通过滑块选择的值决定了我的 for 循环中的重复次数。

我也看到了这个帖子,但不知道这是否是一个类似的问题: For loop inside reactive function in Shiny 希望有人能对此有所了解。

【问题讨论】:

  • 尝试使用observer({})或使用其中一种输出函数,即renderPlotrenderDataTable...
  • 您的第二次尝试是一个不错的选择。但是您需要返回列表:samples &lt;- reactive({ out &lt;- vector("list", input$n_samples) \\ for(i in 1:length(out)){out[[i]] &lt;- ......} \\ out })。我使用“\\”来表示换行符(我们不能在 cmets 中进行换行符)。然后在响应式上下文中执行samples() 以获取此列表。

标签: r loops shiny reactive-programming


【解决方案1】:

他们说增长列表在 R 中是一个坏主意。您应该预先分配列表并迭代地填充空间。以下应用程序将执行此操作。

根据总体 (mtcars),更改滑块会触发绘制与滑块值一样多的 10 个值的样本。调用samples() 可以读取结果。每次滑块变化时,samples() 都会更新(注意:不是samples,它只是一个函数,而是samples(),它是函数调用的结果,绘制的样本):

library(shiny)
library(dplyr)

population <- mtcars


ui <- fluidPage(h4("You have a population of", nrow(population), "values. Choose the number of random sample sets"),
                h5("(each sample contains 10 values):"),
                sliderInput("n", "Number of samples", min=1, max = 1000, value = 5),
                textOutput("summary"))


server <- function(input, output) {

    # a normal function that draws a sample of 10 values
    draw_single_sample <- function(x) sample_n(population, size = 10)

    # A reactive function that takes slider value and produce as many samples as the slider requests
    samples <- reactive(lapply(1:input$n, draw_single_sample))

    # Dependend on samples (thus input$n), print the result of the random draw
    output$summary <- renderText({
        samples_concrete <- samples()
        paste("Finished calculation. You have", length(samples_concrete),
              "random samples of 10 values each Mean values of the first columns:",
              toString(sapply(samples_concrete, function(x) mean(x[[1]]))))
    })
}

shinyApp(ui = ui, server = server)

【讨论】:

    猜你喜欢
    • 2017-03-10
    • 1970-01-01
    • 2017-07-27
    • 2021-05-25
    • 2021-02-09
    • 2018-12-29
    • 2013-07-08
    • 1970-01-01
    • 2018-07-09
    相关资源
    最近更新 更多