如何让 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 中的数据(反转所有手动输入)?
如何实时监听 input 和 textarea输入框值的变化