2016-12-15 84 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