2016-12-15 116 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)) 

是否有一個過濾paramenter,我可以適用於rhandsontable(),讓我來呈現我的數據幀的過濾版本,而無需實際子集劃分它,以使關聯input$hot將不受影響(除中,當然,對於用戶所做的任何編輯)?

我希望用戶在textInput框row中寫入要過濾的行,然後相應地過濾表。當務之急是nrow(hot_to_r(input$hot)) == 1000仍然是TRUE:

render

+0

什麼你的意思是「沒有子集的過濾版本」?你想渲染什麼? –

+0

@StéphaneLaurent,增加了預期的渲染。我遇到的問題是,如果我選擇通過類似'DF [rows,]'的子集(當然是反應性的方式),那麼子集DF將被保存回'input $ hot',行。 –

回答

1

你不能那樣做,有一個過濾器,但可以緩存行,並把數據傳回時,事情的變化。

這是一種在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) 

我會喜歡沒有全局變量賦值和純反應而不是觀察的解決方案,但我不認爲這是可能的。

更新

我提出了我錯過了,因爲我使用的是版本閃亮的無數字控制增量箭頭一致性錯誤的原單。發生這種情況時,如果用數字控制input$row更改了行,但沒有使用Enter鍵或更改焦點關閉rhandsontable input$hot中的編輯,並導致在數據幀DF中更新了錯誤的行。

修復程序正在使用input$hot中的數據來維護此狀態,但這可能是危險的,因爲用戶可以編輯它。或者,也許這是一個功能...

任何方式,這裏是一個屏幕截圖,但你真的有值來玩玩看,它的作品,並沒有錯誤:

enter image description here