[英]R Mechanism behind input$table_rows_all from DT
我對DT包中的input $ 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 ...
我試圖尋找任何文檔,但找不到任何東西。 任何解釋都會有所幫助!
一個簡單的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
,以防止觀察者在init上觸發。
@thothal提出解決方案時,在這里我想直接回答問題。 初始化應用程序時,DataTables僅是空的<divs>
,僅當用戶打開應用程序時,DataTables才會填充內容。 要驗證此行為,請運行您的示例,在瀏覽器中將其打開,然后(在Firefox中)右鍵單擊->“查看頁面源”。 有關說明,請參見此處 。
讓我們在您的應用程序中看到這一點-我添加了一些“調試打印”和一個js警報,可以幫助您:
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"
我對這里發生的事情的理解如下:
1)由於某種原因, renderDataTable
了table2
函數的renderDataTable
。 但是, input$table1_rows_all
仍為NULL
。
2) table1
實際上被渲染(即,加載了行),因此input$table1_rows_all
變得可用。 這將導致observeEvent
進行打印,並導致renderDataTable
對table2
另一個調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.