【问题标题】:How to add recursively modules in shiny through reactivity如何通过反应性在闪亮中添加递归模块
【发布时间】:2020-01-23 16:25:52
【问题描述】:

我是新来的闪亮和 我正在尝试创建一个应用程序,其中 在用户第一次选择之后,一个函数 对预定义的数据集进行一些操作,并且必须打开 新的选择器 UI。 在那个新的选择器 UI 中,用户再次选择了一个新值, 另一个函数对新数据集进行一些操作,依此类推 3~4次以上。

编辑:

加上每次用户选择该值时,它将打开下一个selectUI 当他进行选择时,下一个 ui 将弹出。 我使用了来自闪亮网站的一些示例,但每次都会得到不同的错误:

1)

     Listening on http://127.0.0.1:7178
            Warning: Error in if: argument is not interpretable as logical
              52: server [#12]
            Error in if (reactive(input$Strength_1)) { : 
              argument is not interpretable as logical

2)

    Listening on http://127.0.0.1:7178
    Warning: 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.)
      61: stop
      60: .getReactiveEnvironment()$currentContext
      59: getCurrentContext
      55: .subset2(x, "impl")$get
      54: $.reactivevalues
      52: server [#12]
    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.)

3)

 Listening on http://127.0.0.1:7178
 Warning: Error in force: argument "ui" is missing, with no default [No stack trace available]
 Warning: Error in : evaluation nested too deeply: infinite recursion / options(expressions=)? 93: <Anonymous>

数据集:

Attr_scores %>% head %>% dput
structure(list(scope = c("Sel1", "Sel2", "Sel3", "Sel4", "Sel5", 
"Sel6"), A1 = c(14, 14, 14, 15, 15, 15), A2 = c(13, 14, 14, 14, 
15, 15), A3 = c(13, 13, 14, 13, 12, 15), A4 = c(13, 13, 13, 12, 
12, 11), A5 = c(13, 13, 10, 12, 11, 8), A6 = c(12, 10, 8, 11, 
11, 8)), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"
))

功能:

Attr_score_select <- function(x){
    Attr_scores %>%
        filter(scope == x) %>%
        pivot_longer(-scope) %>% 
        select(value) %>% 
        group_by(value) %>% 
        summarise(n=n())
}
Attr_score_remove <- function(df, score){
    df %>% 
        mutate(n = ifelse(value == score, n-1, n)) %>% 
        mutate(n = ifelse(n == 0, NA, n)) %>% 
        drop_na()     
}

用户界面:


## ui
ui <- fluidPage(
  titlePanel("Dynamically generated user interface components"),
  selectInput(inputId = 'scores',
              label = "Choose scores", 
              choices = c(Choose='', Attr_scores$scope ),
              selectize=TRUE),
  uiOutput("Strength_ui")
)

服务器:

server <- function(input, output) {
  Scores <- reactive(Attr_score_select(input$scores))

  output$Strength_ui <- renderUI({
    #Strength
           selectInput('Strength_1', 
                       label = "Choose Strength score for your character:", 
                       c(Choose='', as.character(Scores()$value))
           )
  })
 # from here on it creates the errors ------------

 if (input$Strength_1){
    observeEvent(input$Strength_1,{
               Scores <- reactive( Scores() %>% 
                                     Attr_score_remove(input$Strength_1))
               insertUI(
                  #Dexterity
                  selectInput('Dexterity_1',
                   label = "Choose Dexterity score for your character:",
                   c(Choose='',as.character(Scores()$value))
                  )  

               ) 
              })

    }
 # if you remove it then it runs ---------------
  }
shinyApp(ui = ui, server = server)

【问题讨论】:

    标签: r shiny shiny-reactivity


    【解决方案1】:

    我无法完全理解您的工作主题,但我会使用反应式表达式和 renderUI 来构建这样的应用程序。

    我的解决方案来了:

    library(shiny)
    library(tidyverse)
    
    Attr_scores <- structure(list(scope = c(
      "Sel1", "Sel2", "Sel3", "Sel4", "Sel5",
      "Sel6"
    ), A1 = c(14, 14, 14, 15, 15, 15), A2 = c(
      13, 14, 14, 14,
      15, 15
    ), A3 = c(13, 13, 14, 13, 12, 15), A4 = c(
      13, 13, 13, 12,
      12, 11
    ), A5 = c(13, 13, 10, 12, 11, 8), A6 = c(
      12, 10, 8, 11,
      11, 8
    )), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))
    
    Attr_score_select <- function(x){
      Attr_scores %>%
        filter(scope == x) %>%
        pivot_longer(-scope) %>% 
        select(value) %>% 
        group_by(value) %>% 
        summarise(n=n())
    }
    Attr_score_remove <- function(df, score){
      df %>% 
        mutate(n = ifelse(value == score, n-1, n)) %>% 
        mutate(n = ifelse(n == 0, NA, n)) %>% 
        drop_na()     
    }
    
    
    ui <- fluidPage(
      titlePanel("Dynamically generated user interface components"),
      selectInput(
        inputId = "scores",
        label = "Choose scores",
        choices = c(Choose = "", Attr_scores$scope),
        selectize = TRUE
      ),
      uiOutput("Strength_ui"),
      uiOutput("Dexterity_1")
    )
    
    
    server <- function(input, output) {
      Scores <- reactive(Attr_score_select(input$scores))
      output$Strength_ui <- renderUI({
        #Strength
        selectInput('Strength_1', 
                    label = "Choose Strength score for your character:", 
                    Scores()$value)
      })
      Scores1 <- reactive(Scores() %>% Attr_score_remove(input$Strength_1) %>% select(value))
      output$Dexterity_1 = renderUI(
            selectInput('Dexterity_1', label = "Choose Dexterity score for your character:",Scores1())
            )  
    
    }
    
    shinyApp(ui = ui, server = server)
    

    问候 帕维尔

    【讨论】:

    • 非常感谢,Pawel,所以问题是我对嵌套函数和 insertUI 使用相同的变量 (Scope)。我的主要事情是,我想首先显示第三个和 UI,但只有在用户选择了第二个值('Strength_1')时才显示它,然后再为之后的下一个值做它等等......
    • 嵌套并不总是个好主意-在您的情况下,它形成了无限循环。您的目标是在用户选择分数和力量之前隐藏敏捷输入。如果用户在初步选择分数/强度后决定更改分数,会发生什么?
    • 我不知道这是不是最好的主意,但他必须再次从 Scores 重新开始。这个想法是创建一个分数桶。当用户选择桶的分数之一时,他应该不能再次使用它。我认为最简单的方法是依次选择每个并每次删除它。最后,用户必须选择 6 个分数,力量和敏捷度是 6 分中的 2 分,所以我必须至少再添加 3 次选择器 UI。
    • 这是否意味着当用户选择Score“Sel1”,然后选择Strength,然后将Score更改为“Sel2”,他应该不能再选择“Sel1”了?
    • 啊,不。如您所见,每次用户选择从数据集派生的选项之一时,函数 Attr_score_remove 都会计算哪些分数仍有待选择。只要他选择了数据集,就可以依次选择其他所有内容。
    猜你喜欢
    • 2020-01-18
    • 2020-03-12
    • 2017-07-27
    • 2020-04-11
    • 1970-01-01
    • 2019-09-01
    • 2016-07-02
    • 2018-07-13
    • 1970-01-01
    相关资源
    最近更新 更多