根据在相同反应函数中创建的输入计算总和

时间:2014-03-07 00:16:58

标签: r shiny

我想知道如何构建输入并在我创建它们的相同反应函数中重用它们。

例如,在此数据框中,第1列是数字输入,最后一列应该是整行的总和。 问题是它们是在相同的反应函数中创建的,然后如果我更改输入值,将重新执行反应函数并重新生成所有表...我试图隔离row.sum但它不起作用。我完全不知道该怎么做。

如果有人可以帮助我......

以下是一个例子:

shiny::runApp(list(
  ui = basicPage(
    tableOutput("table")
  ),
  server = function(input, output, session) {

    output$table <- renderTable({
      mat <- matrix(c(54, 8, 26, 77, 87, 59, 92, 27, 63, 86, 18, 100, 74, 45, 46), nrow = 5, ncol = 3)
      input1 <- paste0("<input id='a", 1:nrow(mat), "' class='shiny-bound-input' type='number' value=1 style='width: 50px;'>")
      row.sum <- unlist(sapply(1:nrow(mat), function(i) input[[sprintf("a%d", i)]] + sum(mat[i,])))
      cbind(input1, mat, row.sum)
    }, sanitize.text.function = function(x) x)

  }
))

感谢您的帮助!

[注意我unlist sapply函数,因为它第一次使用时,尚未创建数字输入,它们都等于NULL,然后sapply返回numeric(0)列表它不适合数据框]

1 个答案:

答案 0 :(得分:1)

您可以尝试这样的事情:

require(shiny)

runApp(list(
  ui = basicPage(
    tableOutput("table")
  ),
  server = function(input, output, session) {

    output$table <- renderTable({
      mat <- matrix(c(54, 8, 26, 77, 87, 59, 92, 27, 63, 86, 18, 100, 74, 45, 46), nrow = 5, ncol = 3)
      dumInput <- sapply(paste0('a', 1:5), function(x) input[[x]])
      dumInput <- ifelse(sapply(dumInput, is.null), 1, dumInput)
      input1 <- paste0("<input id='a", 1:5, "' class='shiny-bound-input' type='number' value=", dumInput, " style='width: 50px;'>" )
      row.sum <- dumInput + rowSums(mat)
      cbind(input1, mat, row.sum)
    }, sanitize.text.function = function(x) x)

  }
))

简要说明。您之前所拥有的是在您创建的input[[a*]]输入中进行更改。然而 然后将输入重置为1.上面的示例将创建的输入中的更改传递给行总和,但也保留了更改的输入值。

另一种方法可能是使用reactiveValues分离逻辑。这可能是优选的,因为对于更复杂的示例可能更容易扩展。

shiny::runApp(list(
  ui = basicPage(
    tableOutput("table")
  ),
  server = function(input, output, session) {

    rv <- reactiveValues(
      mat = matrix(c(54, 8, 26, 77, 87, 59, 92, 27, 63, 86, 18, 100, 74, 45, 46), nrow = 5, ncol = 3)
    )

    output$table <- renderTable({
      dumInput <- sapply(paste0('a', 1:5), function(x) input[[x]])
      dumInput <- ifelse(sapply(dumInput, is.null), 1, dumInput)
      input1 <- paste0("<input id='a", 1:5, "' class='shiny-bound-input' type='number' value=", dumInput, " style='width: 50px;'>" )
      rv$rowsum <- dumInput + rowSums(rv$mat)
      cbind(input1, rv$mat, rv$rowsum)
    }, sanitize.text.function = function(x) x)

  }
))