在 R Shiny 中过滤 rhandsontable 中的行
Filter rows in rhandsontable in R Shiny
我想在 Shiny 应用程序中显示和编辑 rhandsontable
。由于我的数据框相当大,我希望用户能够过滤特定行而不是显示整个 1000 行(参见下面的示例)。我可以基于 input$row
为子集 hot
创建一个反应值,但是只有 DF[input$row,]
被分配给 input$hot
,因此,下次我得到 [= 的值15=] 它 returns 只有一行的数据框。
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
中写入要过滤的行,然后 table 进行相应过滤。 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)
我希望没有全局变量分配和纯反应而不是观察的解决方案,但我认为这是不可能的。
更新
我提出的原件有一个我错过的一致性错误,因为我使用的是没有数字控制增量箭头的 Shiny 版本。当您使用数字控件 input$row
更改行时,没有使用回车键关闭 rhandsontable input$hot
中的编辑或更改焦点,导致错误的行在数据框中更新 input$hot
时发生=13=]。
修复使用 input$hot
中的数据来维持此状态,但这可能很危险,因为用户可以对其进行编辑。或者也许这是一个功能...
无论如何,这是一个屏幕截图,但您确实必须尝试使用这些值才能看到它有效且没有错误:
您可以通过有条件地隐藏行来实现:https://github.com/jrowen/rhandsontable/issues/219#issuecomment-487574898
我想在 Shiny 应用程序中显示和编辑 rhandsontable
。由于我的数据框相当大,我希望用户能够过滤特定行而不是显示整个 1000 行(参见下面的示例)。我可以基于 input$row
为子集 hot
创建一个反应值,但是只有 DF[input$row,]
被分配给 input$hot
,因此,下次我得到 [= 的值15=] 它 returns 只有一行的数据框。
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
中写入要过滤的行,然后 table 进行相应过滤。 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)
我希望没有全局变量分配和纯反应而不是观察的解决方案,但我认为这是不可能的。
更新
我提出的原件有一个我错过的一致性错误,因为我使用的是没有数字控制增量箭头的 Shiny 版本。当您使用数字控件 input$row
更改行时,没有使用回车键关闭 rhandsontable input$hot
中的编辑或更改焦点,导致错误的行在数据框中更新 input$hot
时发生=13=]。
修复使用 input$hot
中的数据来维持此状态,但这可能很危险,因为用户可以对其进行编辑。或者也许这是一个功能...
无论如何,这是一个屏幕截图,但您确实必须尝试使用这些值才能看到它有效且没有错误:
您可以通过有条件地隐藏行来实现:https://github.com/jrowen/rhandsontable/issues/219#issuecomment-487574898