2016-07-11 6 views
7

私は画面の上部にdata.frame情報を、下部に特定の変数の統計情報を表示するShinyアプリケーションを作成しています。ユーザーはDT::datatableオブジェクトと対話することによってdata.frame列をナビゲートできます。位置を維持しながらShiny DataTableの行を更新

ユーザーが変数をクリックすると、編集可能な詳細情報が提示されます。この情報を更新してデータテーブルに反映させたいと思います。私の問題は、私がテーブルを更新すると、レンダリングされ、最初から表示されることです。 編集後にデータテーブルのページと行の選択を保持するにはどうすればよいですか?

ここでは、mtcarsデータセットをDT::datatableに示す最小の実例を示します。フィールドを更新するいくつかのコントロールがあります。 datatableが最初のページに再描画されていることに注目してください。

library(shiny) 

runApp(shinyApp(

    ui = fluidPage(
    title = "minimal-working-example", 
    fluidRow(
     column(3, inputPanel(
     selectInput("field", "Field", choices = names(mtcars)), 
     numericInput("value", "Value", 0), 
     actionButton("submit", "Submit") 
    )), 

     column(9, 
     DT::dataTableOutput("table") 
    ) 
    ) 
), 

    server = function(input, output) { 

    v <- reactiveValues(mtcars=mtcars) 

    observeEvent(input$submit, { 
     v$mtcars[input$field] <- input$value 
    }) 

    output$table <- DT::renderDataTable({ 
     DT::datatable(
     v$mtcars, 
     selection = "single", 
     options = list(pageLength = 5)) 
    }) 
    } 
)) 

セッション情報:

Session info -------------------------- 
setting value      
version R version 3.3.0 (2016-05-03) 
system x86_64, mingw32    
ui  RStudio (0.99.902)   
language (EN)       
collate English_United States.1252 
tz  America/Chicago    
date  2016-07-11     

Packages ------------------------------- 
package  * version  date  source       
DT   0.1.45  2016-02-09 Github (rstudio/[email protected]) 
shiny  * 0.13.0.9000 2016-02-08 Github (rstudio/[email protected]) 
+1

これは難しいが、なんとかです。本質的に何が起こる必要があるのは、テーブルの現在のページが反応的に保存される必要があることです。これはjavascriptの 'Shiny.onInputChange'で行うことができます。その後、コールバックするテーブルをレンダリングして、ページ番号で開いてください。私はチャンスを得るときに完全な答えを書くでしょう。 – Carl

答えて

4

これは、JSまたはそのような何かによってdatatableの構造に入ることなく、Rの内部から行うことができます。

DTパッケージから取得したさまざまなテーブル状態情報を使用して、新しいものをdatatableと同じように更新します。私たちが使用しているものはすべてthis DT documentationに記載されています。

項目1:選択。データテーブルの引数selectionの内側にselected = ...を追加して、行を事前に選択できます。これを変数input$table_rows_selectedと組み合わせて、以前に選択した行を保存し、再描画時にその行を事前に選択することができます。

項目2:ページ。 datatableパッケージには、テーブルのレンダリング時に最初に表示する行を指定するオプションdisplayStartがあります。 Documentation here.ページあたり5行ある場合は、displayStart = 9が3ページ目の表示を開始します(JavaScript配列は0から始まるため、常に1を引いています)。これは現在表示されている行番号のベクトルであるinput$table_rows_currentと組み合わせることができます。最初のエントリ(マイナス1)を保存すると、ディスプレイの開始位置がわかります。以下

完全なコード例:

library(shiny) 

runApp(shinyApp(

    ui = fluidPage(
    title = "minimal-working-example", 
    fluidRow(
     column(3, inputPanel(
     selectInput("field", "Field", choices = names(mtcars)), 
     numericInput("value", "Value", 0), 
     actionButton("submit", "Submit") 
    )), 

     column(9, 
     DT::dataTableOutput("table") 
    ) 
    ) 
), 

    server = function(input, output) { 

    v <- reactiveValues(mtcars=mtcars) 
    previousSelection <- NULL 
    previousPage <- NULL 

    observeEvent(input$submit, { 
     previousSelection <<- input$table_rows_selected 
     previousPage <<- input$table_rows_current[1] - 1 

     v$mtcars[input$field] <- input$value 
    }) 

    output$table <- DT::renderDataTable({ 
     DT::datatable(
     v$mtcars, 
     selection = list(mode = "single", target = "row", selected = previousSelection), 
     options = list(pageLength = 5, displayStart = previousPage)) 
    }) 
    } 
)) 
+0

詳細な応答をありがとう。私はあなたのソリューションで強調表示しているDT APIの機能を見つけました。あなたが私がそれを提出したときにあなたが質問に答えたので、私はあなたに賞金を授与するつもりです。しかし、このソリューションを実装する際に、テーブルのソートが途切れることが判明しました。あなたはどのようにその側面に対処するための任意の考えを持っていますか? – Zelazny7

+1

@ Zelazny7 'datatable'オプション' order'があります。 'datatable'オプション' stateSave = TRUE'を設定すると、現在のテーブルの順序を 'input $ table_state $ order'で取り出すことができます。しかし、このセットは 'displayStart'の後で整理されるので、これはページの選択を間違ってしまいます。私は、(一時的に)データセットを注文し、 'previousPage'行番号が表示される実際のページ(注文後の行番号)を取得するために注文を使用します。それから、私はあなたの 'previousPage' argとしてこれ(モジュラスページの長さ)を使用します。順序列がオーバーライドされている列の場合は、例外ルールも追加されます。 –

関連する問題