【问题标题】:Reactive/Calculate Columns in rhandsontable in shiny- rstudioShiny-rstudio中rhandsontable中的反应/计算列
【发布时间】:2017-10-19 19:52:26
【问题描述】:

我正在尝试向以下交互式表格添加自定义验证。我想要做的如下。该表包含三个变量,即 mpg、cyl 和 disp。假设我编辑第一行的 mpg 值。然后,一旦我按下回车按钮,第一行的 disp 值应自动更改为 disp=mpg/cyl。这里 mpg 值是我编辑的新值。同样,如果我再次在特定行中编辑 cyl,则该特定行的 disp 应自动更改为 disp=mpg/cyl。此外,如果我更改特定行的 disp 值,则该特定行的 cyl 应自动更改为 mpg/cyl。我试图找出一种方法来做到这一点。

library(shiny)
library(datasets)

ui=fluidPage(

rHandsontableOutput("table1")

)

server=function(input, output, session) {

mt=reactive({

datacopy= mtcars[, names(mtcars) %in% c("mpg" , "cyl" , "disp")]
datacopy=data.table(datacopy)
})  


output$table1=renderRHandsontable({

rhandsontable(mt())



})


}



shinyApp(ui,server)

【问题讨论】:

    标签: shiny rstudio rhandsontable


    【解决方案1】:

    我想这会达到你想要的:

    library(shiny)
    library(datasets)
    library(rhandsontable)
    library(data.table)
    
    ui=fluidPage(
    
      rHandsontableOutput("table1")
    
    )
    
    server=function(input, output, session) {
    
      mt=reactive({
    
        datacopy <- NULL
    
        #For initial data upload
        if(is.null(input$table1)){
          datacopy= mtcars[, names(mtcars) %in% c("mpg" , "cyl" , "disp")]
          datacopy=data.table(datacopy) 
    
        }else{
          datacopy = hot_to_r(input$table1)
    
          #If there is change in data
          if(!is.null(input$table1$changes$changes)){
    
            row.no <- unlist(input$table1$changes$changes)[1]
            col.no <- unlist(input$table1$changes$changes)[2]
            new.val <- unlist(input$table1$changes$changes)[4]
            #If the changed value is mpg or cyl
            if(col.no == 0 || col.no == 1){
              datacopy[(row.no+1), 3] = datacopy[(row.no+1), 1]/datacopy[(row.no+1), 2]
            }else{
              datacopy[(row.no+1), 2] = datacopy[(row.no+1), 1]/datacopy[(row.no+1), 3]
            }
    
          }
    
        }
    
        datacopy
    
      })  
    
    
      output$table1=renderRHandsontable({
    
        rhandsontable(mt())
    
      })
    
    }
    
    
    
    shinyApp(ui,server)
    

    希望对你有帮助!

    [编辑]: 根据您编辑的答案,我修改了下面的代码。希望这会有所帮助。

     library(shiny)
        library(datasets)
        library(rhandsontable)
        library(data.table)
    
    
    
        c1= c(rep("0112",3), rep("0113",3),rep("0114",3))
        c2= c( rep(c("A", "B","C"),3))
        c3= c(rep(c("5312", "5421", "5510"),3)) 
        c4=c(rep(c("Area", "Yield", "Prod"),3))
        c5 = c( rep(2010,9))
        c6= c( 4,68,16169,1062,1.5,43225,800,1.25,100)
        data_=cbind(c1,c2,c3,c4,c5,c6)
        data_=as.data.frame(data_)
        names(data_) = c("CPCCode", "Item","ElementCode","El","Year","Value")
        data_$Value=as.numeric(levels( data_$Value))[ data_$Value]
        data_$Year= as.integer(levels( data_$Year))[data_$Year]
        data_$ElementCode = as.character(data_$ElementCode)
        rownames(data_) = NULL
    
    
        ui=fluidPage(
    
          rHandsontableOutput("table1")
    
        )
    
        server=function(input, output, session) {
    
          mt=reactive({
    
            datacopy <- NULL
    
            #For initial data upload
            if(is.null(input$table1)){ 
    
              datacopy <- data_
    
            }else{
              datacopy = hot_to_r(input$table1)
    
              #If there is change in data
              if(!is.null(input$table1$changes$changes)){
    
                row.no <- unlist(input$table1$changes$changes)[1]
                element = datacopy[(row.no + 1), "ElementCode"]
                year= datacopy[(row.no + 1), "Year"]
                cpccode= datacopy[(row.no + 1), "CPCCode"]
                col.no <- unlist(input$table1$changes$changes)[2]
                if(element == "5421"){#Yield
    
                  datacopy$Value[datacopy$CPCCode == cpccode & datacopy$Year == year &  
                                   datacopy$ElementCode == "5510"] =
                    datacopy$Value[datacopy$CPCCode == cpccode & datacopy$Year == year & 
                                     datacopy$ElementCode == "5312"] *
                    datacopy$Value[datacopy$CPCCode == cpccode & datacopy$Year == year & 
                                     datacopy$ElementCode == "5421"]
    
                }else if(element == "5510"){#Area
    
                  datacopy$Value[datacopy$CPCCode == cpccode & datacopy$Year == year & 
                                   datacopy$ElementCode == "5312"] = 
                    datacopy$Value[datacopy$CPCCode == cpccode & datacopy$Year == year &  
                                     datacopy$ElementCode == "5510"] /
                    datacopy$Value[datacopy$CPCCode == cpccode & datacopy$Year == year & 
                                     datacopy$ElementCode == "5421"]
    
                }
    
              }
    
            }
    
            datacopy
    
          }) 
    
          output$table1=renderRHandsontable({
    
            rhandsontable(mt())
    
          })
    
        }
    
    
    
        shinyApp(ui,server)
    

    【讨论】:

    • 非常感谢。它有很大帮助。我不知道更改选项。我想知道 input$table1$changes$changes 给你什么。
    • input$table1$changes$changes是一个列表,其中包含用户在rhandsontable 中所做的更改。 unlist(input$table1$changes$changes) 给你一个向量,它的第一个和第二个元素分别是值被更改的单元格的行号(0 索引)和列号(0 索引),第三个元素是单元格中的前一个值,第四个元素是单元格中的新值。
    • 哦。这对我正在开发的东西非常有用。我没有话要感谢你。干杯!!很棒的东西。
    • 另一个问题:if(col.no == 0 || col.no == 1) 是什么意思?以及你为什么写 (row.no+1) ?
    • col.no == 0 指的是数据集的第一列(mpg),col.no == 1 指的是数据集的第二列(cyl)。因此,根据您问题中给出的条件,我们必须计算新值。 row.no+1 因为你得到的值是零索引的,而 R 是一索引的。希望这能消除您的疑虑!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    • 2017-04-21
    • 2018-04-28
    • 2020-11-11
    • 2015-11-24
    • 2017-04-30
    相关资源
    最近更新 更多