代码之家  ›  专栏  ›  技术社区  ›  Mal_a

输入$table_rows_all from DT后面的R机制

  •  1
  • Mal_a  · 技术社区  · 6 年前

    我有一个关于从DT包输入$table_rows_all的问题。 实际上,我注意到在使用它时,我的代码/表被呈现了不止一次(?)。首先是包含0行的表,然后根据筛选的行--> 我的实际应用程序非常复杂,因此在这次操作中我会准时发布

    这里有一个简单的例子来说明我的意思:

    library(shiny)
    library(DT)
    
    ui <- bootstrapPage(
    dataTableOutput("table1"),
    dataTableOutput("table2"))
    
    server <- function(input, output) {
    
    output$table1 <- renderDataTable({
    datatable(iris,filter="top")})
    
    output$table2 <- renderDataTable({
    data <- iris[input$table1_rows_all,]
    str(data)
    datatable(data)})
    }
    shinyApp(ui = ui, server = server)
    

    'data.frame':   0 obs. of  5 variables:
     $ Sepal.Length: num 
     $ Sepal.Width : num 
     $ Petal.Length: num 
     $ Petal.Width : num 
     $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 
    'data.frame':   0 obs. of  5 variables:
     $ Sepal.Length: num 
     $ Sepal.Width : num 
     $ Petal.Length: num 
     $ Petal.Width : num 
     $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 
    'data.frame':   150 obs. of  5 variables:
     $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
     $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
     $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
     $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
     $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
    

    我试图寻找任何文件,但找不到任何东西。任何解释都是有用的!

    2 回复  |  直到 6 年前
        1
  •  1
  •   thothal    6 年前

    简单的 req 防止这种行为:

    library(shiny)
    library(DT)
    
    ui <- bootstrapPage(
      dataTableOutput("table1"),
      dataTableOutput("table2"))
    
    server <- function(input, output) {
    
      output$table1 <- renderDataTable({
        datatable(iris,filter="top")
      })
    
      output$table2 <- renderDataTable({
        req(input$table1_rows_all) ## run the following code only if table1_rows_all is truthy
        data <- iris[input$table1_rows_all,]
        str(data)
        datatable(data)
      })
    }
    shinyApp(ui = ui, server = server)
    
    # 'data.frame':   150 obs. of  5 variables:
    #  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
    #  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
    #  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
    #  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
    #  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
    

    reactives 每当有什么改变 oberserver/render*

    为了 observeEvent ignoreInit 它可以防止观察者在初始化时触发。

        2
  •  1
  •   pieca    6 年前

    虽然@thothal提出了一个解决方案,但在这里我想直接回答这个问题。初始化应用程序时,数据表只是空的 <divs> here .

    library(shiny)
    library(DT)
    
    ui <- bootstrapPage(
      shiny::tags$script(
        "$(document).on('shiny:sessioninitialized', function(event) {
          alert('Connected to the server');
        });"
      ),
      dataTableOutput("table1"),
      dataTableOutput("table2"))
    
    server <- function(input, output) {
    
      #  this ignores input$table1_rows_all being NULL and runs only when there is a value
      observeEvent(
        input$table1_rows_all,
        {
          print("observeEvent called")
          print(input$table1_rows_all)
        }
      )
    
      output$table1 <- renderDataTable({
        print("renderDataTable -- table 1 called")
        datatable(iris,filter="top")
      })
    
      output$table2 <- renderDataTable({
        print("renderDataTable -- table 2 called")
        if (is.null(input$table1_rows_all)) {
          print("input$table1_rows_all is NULL")
        }
        data <- iris[input$table1_rows_all,]
        datatable(data)
      })
    }
    
    shinyApp(ui = ui, server = server, options = list(launch.browser = FALSE))
    

    运行应用程序并在浏览器中打开它。您看到会话已初始化,并且 renderDataTable input$table1_rows_all 只是现在不存在——这就是为什么您有0行。

    [1] "renderDataTable -- table 1 called"
    [1] "renderDataTable -- table 2 called"
    [1] "input$table1_rows_all is NULL"
    

    单击“确定”继续。随后打印以下行:

    [1] "renderDataTable -- table 2 called"
    [1] "input$table1_rows_all is NULL"
    [1] "observeEvent called"
      [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28
     [29]  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56
     [57]  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84
     [85]  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100 101 102 103 104 105 106 107 108 109 110 111 112
    [113] 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
    [141] 141 142 143 144 145 146 147 148 149 150
    [1] "renderDataTable -- table 2 called"
    

    我对这件事的理解如下:

    呈现数据表 table2 函数被调用。然而, 输入$table1_rows_all 仍然 NULL

    2个) table1 实际上得到了呈现(即加载了行),所以 输入$table1_rows_all 变得可用。结果打印自 observeEvent 呈现数据表 对于 表2