2016-12-15 1 views
1

Shiny 응용 프로그램에서 rhandsontable을 표시하고 편집하고 싶습니다. 데이터 프레임이 상당히 크기 때문에 사용자가 전체 1000 개의 행을 표시하는 대신 특정 행을 필터링 할 수 있기를 원합니다 (아래 예 참조). input$row을 기반으로 하위 집합 hot에 대한 반응 값을 만들 수 있지만 DF[input$row,]input$hot에 할당되므로 다음에 input$hot 값을 얻습니다. 단 하나의 행만있는 데이터 프레임을 반환합니다. R의 rhandsontable 행 필터링 Shiny

library(shiny) 
library(rhandsontable) 

ui <- shinyUI(fluidPage(
    numericInput("rows","row to filter",value = 1), 
    rHandsontableOutput("hot") 
)) 

server <- shinyServer(function(input, output, session) { 

    # render handsontable output 
    output$hot <- renderRHandsontable({ 
    if (!is.null(input$hot)) { 
     DF <- hot_to_r(input$hot) 
    } else { 
     set.seed(42) 
     DF <- data.frame(a=1:1000, b= rnorm(1000)) 
    } 
    rhandsontable(DF) 
    }) 

}) 

runApp(list(ui=ui, server=server)) 

인가가 연결된 input$hot 제외하고 (영향을받지 않습니다 있도록의, 내가 실제로 서브 세트하지 않고 내 데이터 프레임의 필터링 된 버전을 렌더링 할 수있는 것 내가 rhandsontable()에 적용 할 수있는 필터링 paramenter 물론, 사용자가 수정 한 내용은 무엇입니까?)

사용자가 textInput 상자에 필터 할 행을 쓰고 싶으면 row 그리고 그에 따라 필터링 할 표를 원합니다. 당신은 필터, 그렇게 할 수 없어

render

+0

무엇 하위 집합이없는 필터링 된 버전 "을 의미합니까? 무엇을 렌더링하고 싶습니까? –

+0

@ StéphaneLaurent, 예상 렌더링을 추가했습니다. 내가 가진 문제는'DF [rows,]'와 같은 방식으로 DF를 부분 집합으로 선택하면 (물론 반응적인 방식으로) 부분 집합 DF가'input $ hot'에 저장되고 나머지는 999 행. –

답변

1

,하지만 당신은 행을 캐시, 사물이 변경 될 때 데이터를 다시 넣을 수 있습니다 : nrow(hot_to_r(input$hot)) == 1000가 TRUE로 계속 필수적이다.

이것은 Shiny에서하는 한 가지 방법입니다. 내가 생각했던 것보다 옳은 길을 찾기가 더 어려워진 다른 방법들도 시도해 보았습니다. 그래서 나 역시 학습 경험이었습니다.

library(shiny) 
library(rhandsontable) 

set.seed(1234) 

# Data and a couple utility functions 
nrow <- 1000 
DF <- data.frame(a = 1:nrow,b = abs(rnorm(nrow))) 
lastrow <- 1 

getrowfromDF <- function(idx) { 
    return(DF[idx,]) 
} 

putrowintoDF <- function(rowdf,idx) { 
    for (ic in 1:ncol(DF)) { 
    DF[idx,ic] <<- rowdf[1,ic] 
    } 
} 

u <- shinyUI(fluidPage(
    numericInput("row","row to filter",value = lastrow,min = 1,max = nrow(DF)), 
    verbatimTextOutput("rowstat"), 
    rHandsontableOutput("hot") 
)) 

s <- shinyServer(function(input,output,session) { 

    # reactive row status 
    rs <- reactiveValues() 
    rs$lstrow <- rs$currow <- 1 

    # record changes from user editing here 
    observeEvent(input$hot, { 
    if (!is.null(input$hot)) { 
     ndf <- data.frame(input$hot$data) # convert from list 
     #putrowintoDF(ndf,rs$currow) # original - has inconsistency issue when 
            # you change rows without closing edit 
            # with enter key in rhandsontable grid input$hot 
     putrowintoDF(ndf,ndf[1,1])  # new, consistent, but relies on editable data for state 
    } 
    }) 

    # slide the row to the new position here 
    observeEvent(input$row, { 
    rs$lstrow <<- rs$currow 
    rs$currow <<- input$row 
    }) 


    # render handsontable output 
    output$hot <- renderRHandsontable({ 
    ndf <- getrowfromDF(rs$currow) 
    rhandsontable(ndf) 
    }) 

    # just for debug 
    output$rowstat <- renderPrint({ sprintf("rowstat: cur:%d last:%d",rs$currow,rs$lstrow) }) 

}) 
shinyApp(ui = u,server = s) 
내가 전역 변수 할당 및 순수 reactives없이 해결책을 좋아했을

대신의 관찰,하지만 난 그게 가능하다고 생각하지 않습니다.

업데이트

나는 수치 제어 증가 화살표없이 빛나는 버전을 사용했기 때문에 내가 놓친 일관성 오류가 있었다 제기의 orginal. Enter 키 또는 포커스 변경으로 중비 문자 input$hot의 편집을 닫지 않고 숫자 컨트롤 input$row으로 행을 변경하고 데이터 프레임 DF에서 잘못된 행을 업데이트하는 일이 발생했습니다.

이 수정 사항은 input$hot의 데이터를 사용하여이 상태를 유지하지만 사용자가 편집 할 수 있으므로 위험 할 수 있습니다. 아니면 그 기능입니다 ...

어떤 방법, 여기에 스크린 샷,하지만 당신은 정말 작동하고 어떤 버그가 없다고 볼 수있는 값으로 재생할 수 있습니다

enter image description here