2016-07-11 2 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)) 
    }) 
    } 
)) 

세션 정보 :

이 그와 같은 JS를 통해 datatable의 구조 또는 무언가로받지 않고 R 내부에서 수행 할 수 있습니다
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

이 까다로운하지만 행할 수있다. 본질적으로 일어날 필요가있는 것은 테이블의 현재 페이지가 반응 적으로 저장되어야하며, 이는 자바 스크립트에서'Shiny.onInputChange'로 수행 될 수 있습니다. 그런 다음 콜백 테이블을 렌더링하면 이전에 있던 페이지 번호에서 열 수 있습니다. 나는 기회가 생길 때 완전한 대답을 쓸거야. – Carl

답변

4

.

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로 사용할 것입니다. 순서 지정 열이 재정의 된 경우 예외 규칙이 추가됩니다. –

관련 문제