如何让 rhandsontable 对输入值的变化和自身的变化做出反应?

Posted

技术标签:

【中文标题】如何让 rhandsontable 对输入值的变化和自身的变化做出反应?【英文标题】:How can I get a rhandsontable to react to changes in input values and to changes in itself? 【发布时间】:2020-05-11 08:18:04 【问题描述】:

所以我想在 rHOT 中有一个值表,随时更新 1) 底层数据通过响应式输入进行更新 和 2) 每当您更新 rHOT 表中的值时。

当 input$ 改变时,下面的代码会刷新真实的 avgs/cums 表。 然后我可以在 rHOT 表的 avgs 中输入新值,然后 cums 就会更新。

但是当您再次更改 input$ 时,我想再次刷新 rHOT 表的值,并且仍然可以接受其自己的 Avg 行中的更改。


library(dplyr)
library(shiny)
library(shinydashboard)
library(rhandsontable)

accdntprd<-1:5
StatData<-as.data.frame(matrix(c(100, 150, 175, 180, 200, 110, 
                                 168, 192, 205, 210, 115, 169,
                                 202, 200, 100, 125, 185, 100, 
                                 120, 130, 150, 180, 190, 200, 210), 
                               nrow = 5, byrow = TRUE))
StatData<-as.data.frame(cbind(accdntprd,StatData[1:5,]))


ui <- dashboardPage(
  dashboardHeader(title="Shiny"),
  dashboardSidebar(
    sidebarMenu(id="tabs", menuItem("Blocks", tabName = "Blocks"))),
  dashboardBody(tabItems(

    tabItem("Blocks",
            fluidRow(box(width=12
                         ,div(tableOutput("DFs"))
                         ,div(rHandsontableOutput("rTable"))      
            )),
            fluidRow(width=12,
                     box(radioButtons("SelAvgMeth", "averaging", choices= c("straight", "trim"), selected = "straight"))     
            )
    )
  ))
)

server<-function(input, output) 

  observeEvent(
    input$SelAvgMeth, 

      rTable_content <<- reactive(

        t<-ifelse(input$SelAvgMeth=="trim",1, 0)
        Avgs<-t(sapply((2:5),function(i)mean(StatData[, i+1]/StatData[, i], trim = t/4)))

        Avgs<-rev(Avgs)
        Cums<-cumprod(Avgs)
        DF<-t(as.data.frame(cbind(rev(Avgs), rev(Cums))))
        DF<-data.frame(DF)
        rownames(DF)<-c("Avgs", "Cums")
        return(DF)

      )

      output$DFs<-renderTable(
        rTable_content()
      , digits = 3, spacing = "xs", rownames = TRUE)

    )   


  MyChanges <- reactive(

    if(is.null(input$rTable)|(identical(rTable_content(),input$rTable)))
      return(rTable_content())
     else 
      selDF<- as.data.frame(hot_to_r(input$rTable)) 
      selDF[2,]<-rev(cumprod(rev(as.numeric(selDF[1,]))))
      rownames(selDF)<-c("Avgs", "Cums")
      return(selDF)
     
  )
  output$rTable <- renderRHandsontable(
    rhandsontable(MyChanges())%>% hot_cols(format = "0.000")
  )





shinyApp(ui, server)


我知道观察事件并不是真正必要的,但让我们把它留在那里,以防我想控制其他输入。

如果我问错了,请原谅我。代码是可重现的。

在图片中应该如何工作:

    Initial

    Select Trim

    3。 Accept rHOT changes in top row and auto calculate bottom row. No changes to StatData

【问题讨论】:

抱歉,我还是有点糊涂。每次更改 input$SelAvgMeth 单选按钮时,您的 rTable_content 似乎都会根据您原来的 StatData 信息进行更新。因此,如果您更改了 rHOT 值,rTable_content 应该如何重新计算?它还需要来自StatData 的原始值吗?如果是这样,结果会不会总是与更改后的 rHOT 表不同?也许在您的 rHOT 表更改后rTable_content 应该做什么的具体示例可能会有所帮助。 当 rTable_content 改变时,rhot 表也应该随之改变。这可以通过将 myChanges 设置为 rtable_content 来完成。然后 rhot 表可以有用户输入的更改,并且 rHOT 表应该显示用户的更改。 StatData 和 rHOT 应该是独立的,但是 rHOT 应该在 StatData 更改时重置。我将添加屏幕截图。 【参考方案1】:

感谢您提供更多详细信息。

我可能会创建单独的reactiveValues 来存储您的表格并为您提供更大的灵活性。

我仍然不清楚的部分是如果在 rHOT 表更改后选择单选按钮会发生什么。现在,它只是根据原始数据设置两个表。

看看这是否有你正在寻找的行为。

server<-function(input, output) 

  rv <- reactiveValues(table1 = NULL,
                       table2 = NULL)

  observeEvent(input$SelAvgMeth,
    t <- ifelse(input$SelAvgMeth == "trim", 1, 0)
    Avgs<-t(sapply((2:5),function(i)mean(StatData[, i+1]/StatData[, i], trim = t/4)))
    Avgs<-rev(Avgs)
    Cums<-cumprod(Avgs)
    DF<-t(as.data.frame(cbind(rev(Avgs), rev(Cums))))
    DF<-data.frame(DF)
    rownames(DF)<-c("Avgs", "Cums")
    rv$table1<-rv$table2<-DF
  )

  output$DFs<-renderTable(
    rv$table1
  , digits = 3, spacing = "xs", rownames = TRUE)

  observe(
    if (!is.null(input$rTable))
      selDF<- as.data.frame(hot_to_r(input$rTable)) 
      selDF[2,]<-rev(cumprod(rev(as.numeric(selDF[1,]))))
      rownames(selDF)<-c("Avgs", "Cums")
      rv$table2 <- selDF
     
  )

  output$rTable <- renderRHandsontable(
    rhandsontable(rv$table2) %>%
      hot_cols(format = "0.000")
  )


【讨论】:

你做到了!这正是我一直在寻找的。我不知道为什么我让它变得比原来更复杂。一旦单选按钮更改,我确实希望两个表都更新——撤消我在 rhot 中所做的任何更改。但允许我根据刷新的值更新 rhot。非常感谢!

以上是关于如何让 rhandsontable 对输入值的变化和自身的变化做出反应?的主要内容,如果未能解决你的问题,请参考以下文章

在 R Shiny 中,如何使用 actionButton 重置 rhandsontable 中的数据(反转所有手动输入)?

rhandsontable 在闪亮问题中的输入

RHandsontable 不正确的输入转换,当使用格式时

如何实时监听 input 和 textarea输入框值的变化

使用 rhandsontable 注册对 afterOnCellMouseDown 事件的回调

如何将 'afterColumnResize' 事件与 'rhandsontable' 一起使用?