【问题标题】:Filter rows in rhandsontable in R Shiny在 R Shiny 中过滤 rhandsontable 中的行
【发布时间】:2017-04-30 22:01:40
【问题描述】:

我想在 Shiny 应用中显示和编辑 rhandsontable。由于我的数据框相当大,我希望用户能够过滤特定的行,而不是显示整个 1000 行(参见下面的示例)。我可以根据input$row 为子集hot 创建一个反应值,但是只有DF[input$row,] 被分配给input$hot,因此,下次我得到input$hot 的值时,它会返回一个只有一排。

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))

是否有一个过滤参数可以应用于rhandsontable(),它允许我渲染我的数据框的过滤版本而不实际对其进行子集化,因此链接的input$hot 不会受到影响(除了,当然,对于用户所做的任何编辑)?

我希望用户在文本输入框row 中写入要过滤的行,然后相应地过滤表格。 nrow(hot_to_r(input$hot)) == 1000 必须继续为真:

【问题讨论】:

  • “没有子集的过滤版本”是什么意思?你想渲染什么?
  • @StéphaneLaurent,添加了预期的渲染。我遇到的问题是,如果我选择像 DF[rows,] 这样子集 DF(当然是以反应方式),那么子集 DF 将被保存回 input$hot 并且我会丢失其他 999 行。

标签: javascript r filter shiny rhandsontable


【解决方案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)

我本来希望没有全局变量分配和纯反应而不是观察的解决方案,但我认为这是不可能的。

更新

我提出的原件有一个我错过的一致性错误,因为我使用的是没有数字控制增量箭头的 Shiny 版本。当您使用数字控件input$row 更改行时发生这种情况,而没有使用回车键或更改焦点关闭rhandsontable input$hot 中的编辑,并导致在数据框DF 中更新错误的行。

修复是使用input$hot 中的数据来维持此状态,但这可能很危险,因为用户可以对其进行编辑。或者也许这是一个功能......

无论如何,这是一个屏幕截图,但您确实必须使用这些值来查看它是否有效并且没有错误:

【讨论】:

    【解决方案2】:

    您可以通过有条件地隐藏行来做到这一点:https://github.com/jrowen/rhandsontable/issues/219#issuecomment-487574898

    【讨论】:

      猜你喜欢
      • 2018-04-28
      • 2017-12-02
      • 2020-08-15
      • 2022-11-22
      • 2018-05-18
      • 1970-01-01
      • 2021-08-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多