如何修改反应链以便最后修改的对象控制其他链接的对象?

2024-05-23

[新注释 1:最终解决的代码发布在最底部,反映了 ismirsehregal 于 2021 年 12 月 3 日的解决方案,以及一些标记为“# ADDED”和“# MODIFIED”的小调整。 ADD 是为了解决我在矩阵 2 添加值后从矩阵 1 中删除行时遇到的错误(如下所述),而“MODIFIED”是为了符合矩阵 1 和 2 的列标题(它们没有不同的值)列标题)。

运行下面的代码时,我希望反应链中修改的最后一个对象能够“控制”或“支配”该反应链中的其他对象。在此代码中,链接的反应对象是“matrix1”和“matrix2”。输入到矩阵 2 下游的矩阵 1,并输入到矩阵 1 上游的矩阵 2 的前 2 列。按照草案,矩阵 2 的输入胜过矩阵 1 的输入。我希望最后输入的矩阵能够胜过另一个矩阵。有人可以帮我弄这个吗?

底部的图像有助于说明。

我已经搞砸了isolate()和其他事情来尝试让它按照我想要的方式工作。我还遇到了矩阵陷入循环的问题,其中值在两个矩阵之间来回反弹。我没有完全掌握isolate() yet.

Code:

library(dplyr)
library(ggplot2)
library(shiny)
library(shinyMatrix)

sumMat <- function(x){return(rep(sum(x,na.rm = TRUE), 10))}

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      matrixInput("matrix1",
                  label ="Matrix 1 (scenario 1):",
                  value = matrix(c(60,5),ncol=2,dimnames=list(NULL,c("X","Y"))),
                  rows = list(extend = TRUE, delete = TRUE),
                  class = "numeric"),
      actionButton(inputId = "showMat2", "Add scenarios"),br(),br(),
    ),
    mainPanel(plotOutput("plot"))
  )
)

server <- function(input, output, session){

  observeEvent(input$matrix1, {
    tmpMat1 <- input$matrix1
    if(any(rownames(input$matrix1) == "")){rownames(tmpMat1) <- paste("Row", seq_len(nrow(input$matrix1)))    }
    isolate(updateMatrixInput(session, inputId = "matrix1", value = tmpMat1))
  })
  
  observeEvent(input$showMat2,{
    showModal(
      modalDialog(
        matrixInput("matrix2",
                    label = "Matrix 2:",
                    value = input$matrix1,
                    rows = list(extend = TRUE, delete = TRUE),
                    cols = list(extend = TRUE, delta = 2, delete = TRUE, multiheader = TRUE),
                    class = "numeric"),
        footer = tagList(modalButton("Close"))
      ))
    observeEvent(input$matrix2, {
      tmpMat2 <- input$matrix2
      rownames(tmpMat2) <- paste("Row", seq_len(nrow(input$matrix2)))
      colnames(tmpMat2) <- paste("Scenario",rep(1:ncol(tmpMat2),each=2,length.out=ncol(tmpMat2)))
      isolate(updateMatrixInput(session, inputId = "matrix2", value = tmpMat2))
      isolate(updateMatrixInput(session, inputId = "matrix1", value = tmpMat2[,1:2]))
    })
  })
  
  plotData <- reactive({
    tryCatch(
      lapply(seq_len(ncol(input$matrix1)/2), 
             function(i){
               tibble(
                 Scenario= colnames(input$matrix1)[i*2-1],X=seq_len(10),
                 Y=sumMat(input$matrix1[,(i*2-1):(i*2), drop = FALSE])
               )
             }) %>% bind_rows(),
      error = function(e) NULL
    )
  })
  
  output$plot <- renderPlot({
    plotData() %>% ggplot() + 
      geom_line(aes(x = X, y = Y, colour = as.factor(Scenario))) +
      theme(legend.title=element_blank())
  })
}

shinyApp(ui, server)

新注释 1:最终解决的代码如下

sumMat <- function(x) {return(rep(sum(x, na.rm = TRUE), 10))}

ui <- fluidPage(sidebarLayout(
  sidebarPanel(
    matrixInput(
      "matrix1",
      label = "Matrix 1:", # MODIFIED HEADER
      value = matrix(c(60,5),ncol=2,dimnames=list(NULL,rep("Scenario 1",2))), # MODIFIED HEADER
      rows = list(extend = TRUE, delete = TRUE),
      cols = list(multiheader = TRUE), # ADD
      class = "numeric"
    ),
    actionButton(inputId = "showMat2", "Add scenarios"),br(),br(),
  ),
  mainPanel(plotOutput("plot"))
))

server <- function(input, output, session) {
  
  currentMat <- reactiveVal(isolate(input$matrix1))
  
  observeEvent(input$matrix1, {
    tmpMat1 <- input$matrix1
    if(any(rownames(input$matrix1)=="")){rownames(tmpMat1)<-paste("Row",seq_len(nrow(input$matrix1)))}
    updateMatrixInput(session, inputId = "matrix1", value = tmpMat1)
    
    tmpMat2 <- currentMat()
    
    if(nrow(tmpMat1) > nrow(tmpMat2)){tmpMat2 <- rbind(tmpMat2, rep(NA, ncol(tmpMat2)))}
  
    # ADDED
    if(nrow(tmpMat2) > nrow(tmpMat1)){tmpMat1 <- rbind(tmpMat1, rep(NA, ncol(tmpMat1)))}
  
    currentMat(cbind(tmpMat1[drop=FALSE], tmpMat2[,-1:-2,drop=FALSE]))
  })
  
  observeEvent(input$showMat2, {
    showModal(modalDialog(
      matrixInput(
        "matrix2",
        label = "Matrix 2:",
        value = currentMat(),
        rows = list(extend = TRUE, delete = TRUE),
        cols = list(extend = TRUE,delta = 2,delete = TRUE,multiheader = TRUE),
        class = "numeric"
      ),
      footer = tagList(modalButton("Close"))
    ))
  })
  
  observeEvent(input$matrix2, {
    tmpMat2 <- input$matrix2
    rownames(tmpMat2) <- paste("Row", seq_len(nrow(input$matrix2)))
    colnames(tmpMat2) <-
      paste("Scenario", rep(1:ncol(tmpMat2),each = 2,length.out = ncol(tmpMat2)))
    currentMat(tmpMat2)
    updateMatrixInput(session, inputId = "matrix2", value = tmpMat2)
    updateMatrixInput(session, inputId = "matrix1", value = tmpMat2[, 1:2, drop = FALSE])
  })
  
  plotData <- reactive({
    tryCatch(
      lapply(seq_len(ncol(input$matrix1) / 2),
             function(i) {
               tibble(
                 Scenario = colnames(input$matrix1)[i * 2 - 1],
                 X = seq_len(10),
                 Y = sumMat(input$matrix1[, (i * 2 - 1):(i * 2), drop = FALSE])
               )
             }) %>% bind_rows(),
      error = function(e)
      NULL
    )
  })
  
  output$plot <- renderPlot({
    plotData() %>% ggplot() +
      geom_line(aes(
        x = X,
        y = Y,
        colour = as.factor(Scenario)
      )) +
      theme(legend.title = element_blank())
  })
}

shinyApp(ui, server)

以下似乎有效:

  • 记得使用drop = FALSE
  • 从不嵌套观察者

library(dplyr)
library(ggplot2)
library(shiny)
library(shinyMatrix)

sumMat <- function(x) {
  return(rep(sum(x, na.rm = TRUE), 10))
}

ui <- fluidPage(sidebarLayout(
  sidebarPanel(
    matrixInput(
      "matrix1",
      label = "Matrix 1 (scenario 1):",
      value = matrix(c(60, 5), ncol = 2, dimnames = list(NULL, c("X", "Y"))),
      rows = list(extend = TRUE, delete = TRUE),
      class = "numeric"
    ),
    actionButton(inputId = "showMat2", "Add scenarios"),
    br(),
    br(),
  ),
  mainPanel(plotOutput("plot"))
))

server <- function(input, output, session) {
  
  currentMat <- reactiveVal(isolate(input$matrix1))
  
  observeEvent(input$matrix1, {
    tmpMat1 <- input$matrix1
    if (any(rownames(input$matrix1) == "")) {
      rownames(tmpMat1) <- paste("Row", seq_len(nrow(input$matrix1)))
    }
    updateMatrixInput(session, inputId = "matrix1", value = tmpMat1)
    
    tmpMat2 <- currentMat()
    if(nrow(tmpMat1) > nrow(tmpMat2)){
      tmpMat2 <- rbind(tmpMat2, rep(NA, ncol(tmpMat2)))
    }
    if(nrow(tmpMat2) > nrow(tmpMat1)){
      tmpMat1 <- rbind(tmpMat1, rep(NA, ncol(tmpMat1)))
    }
    currentMat(cbind(tmpMat1, tmpMat2[,-1:-2]))
  })
  
  observeEvent(input$showMat2, {
    showModal(modalDialog(
      matrixInput(
        "matrix2",
        label = "Matrix 2:",
        value = currentMat(),
        rows = list(extend = TRUE, delete = TRUE),
        cols = list(
          extend = TRUE,
          delta = 2,
          delete = TRUE,
          multiheader = TRUE
        ),
        class = "numeric"
      ),
      footer = tagList(modalButton("Close"))
    ))
  })
  
  observeEvent(input$matrix2, {
    tmpMat2 <- input$matrix2
    rownames(tmpMat2) <- paste("Row", seq_len(nrow(input$matrix2)))
    colnames(tmpMat2) <-
      paste("Scenario", rep(
        1:ncol(tmpMat2),
        each = 2,
        length.out = ncol(tmpMat2)
      ))
    currentMat(tmpMat2)
    updateMatrixInput(session, inputId = "matrix2", value = tmpMat2)
    updateMatrixInput(session, inputId = "matrix1", value = tmpMat2[, 1:2, drop = FALSE])
  })
  
  plotData <- reactive({
    tryCatch(
      lapply(seq_len(ncol(input$matrix1) / 2),
             function(i) {
               tibble(
                 Scenario = colnames(input$matrix1)[i * 2 - 1],
                 X = seq_len(10),
                 Y = sumMat(input$matrix1[, (i * 2 - 1):(i * 2), drop = FALSE])
               )
             }) %>% bind_rows(),
      error = function(e)
        NULL
    )
  })
  
  output$plot <- renderPlot({
    plotData() %>% ggplot() +
      geom_line(aes(
        x = X,
        y = Y,
        colour = as.factor(Scenario)
      )) +
      theme(legend.title = element_blank())
  })
}

shinyApp(ui, server)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何修改反应链以便最后修改的对象控制其他链接的对象? 的相关文章

  • 在 R 中绘制逻辑回归的两条曲线

    我正在 R glm 中运行逻辑回归 然后我设法绘制结果 我的代码如下 temperature glm glm Response Temperature data mydata family binomial plot mydata Temp
  • r - 选择每组最后出现的 n 次

    情况 我有一个数据框df df lt structure list person structure c 1L 1L 1L 1L 2L 2L 2L 3L 3L Label c pA pB pC class factor date struc
  • R:如何应用输出多列数据帧的函数(使用 dplyr)?

    我想查找数据框中某一特定列与所有其他列之间的相关性 p 值和 95 CI broom 包提供了一个示例 说明如何使用带有 dplyr 和管道的 cor test 在两列之间执行此操作 对于 mtcars 和 mpg 列 我们可以与另一列进行
  • Rstudio 中的 Sweave — pdf 中没有显示任何图

    这里是 Sweave Latex 新手 我在生成常规函数输出时没有问题 但绘图没有显示 这是一个基本示例 documentclass article begin document SweaveOpts concordance TRUE lt
  • R:大向量的高效迭代子集和过滤

    我想更快地执行以下操作 Logic 我有一个向量big共 4 个元素1 2 3 4 我还有一个相同长度的阈值向量1 1 3 1 4 1 5 1 我希望每个元素找到第一个元素的索引next元素高于相应的阈值 在这种情况下 我的预期输出是 2
  • 如何处理“不符合”的数组?

    如何对两个数组进行逐元素算术运算 在第一维度中一致 但也有一个额外的维度 示例 乘法数组a 3 x 3 x 2 按数组b 3 x 3 a lt array 1 18 dim c 3 3 2 b lt diag 3 由于数组不一致 因此以下操
  • 长变量名在 dplyr 中失败

    长度超过 39 个字符的字符串在 dplyr 中失败 返回错误 错误 索引超出范围 我错过了什么还是这是一个错误 40 个字符不起作用 library dplyr names iris 5 lt vvv 5vvv10vvv15vvv20vv
  • 如何在R中得到一个大的稀疏矩阵? (> 2^31-1)

    我使用一些 C 代码从数据库中获取文本文件 并从该文件创建 dgcMatrix 类型稀疏矩阵Matrix包裹 我第一次尝试构建一个具有超过 2 31 1 个非稀疏成员的矩阵 这意味着稀疏矩阵对象中的索引向量也必须比该限制长 不幸的是 向量似
  • 带有用户输入的knitr

    我正在使用 R markdown 并使用 Rstudio 来 Knit 我有以下 R markdown 文件 title Untitled author date output html document r setup include F
  • R从列表中提取数据框,列名中没有前缀

    我在列表中放置了一个数据框 然后 当尝试将其提取回来时 我得到了该数据帧的所有以列表键为前缀的列名称 有没有办法完全按照最初传递的方式提取数据帧 cols lt c column1 Column2 Column3 df1 lt data f
  • 将summary()写入as.data.frame以在ggplot / R中使用

    请查找 af 数据样本t below 我正在使用以下方法进行竞争风险分析etmCIF来自etm package 产生以下结果 这很好 但需要更好的图形 曾经有一个ggtrans etm函数将数据导入ggplot 然而 这个功能显然被删除了
  • 用于清除工作空间和转储存储的 R 全局函数

    我希望创建一个全局函数来清除我的工作区并转储我的内存 我将我的函数称为 cleaner 并希望它执行以下代码 remove list ls gc 我尝试在全局环境中创建该函数 但是当我运行它时 控制台仅打印该函数的文本 在我要获取的函数文件
  • dplyr 中的 Summarize 是否可以不删除数据框中的其他列?

    我有一个包含三列的数据框 我正在尝试进行简单的总结以查找数据框中每个城市的最高温度 但同时保留每个最高温度列出的日期 这是数据框 我们称之为 maxT new ID Date Max TemperatureF 1 TUS 1960 04 0
  • R-了解 akima::interp 结果中的 NA 值

    我有以下数据框 ref dat k Intensity Slope 1 0 021467214 33 16 2 0 012444759 33 8 3 0 006079156 33 4 4 0 003792025 33 2 5 0 02276
  • 将列表中的列转换为 R 中的数据框

    我有使用 R 创建的以下列表 set seed 326581 X1 rnorm 10 0 1 Y1 rnorm 10 0 2 data data frame X1 Y1 lst lt replicate 100 df smpl lt dat
  • dplyr,do(),从模型中提取参数而不丢失分组变量

    R 帮助中关于 do 的示例略有不同 by cyl lt group by mtcars cyl models lt by cyl gt do mod lm mpg disp data coefficients lt models gt d
  • 如何在 R 中为传单中的数值变量设置不对称颜色渐变

    我想让传单调色板以零为中心 红白绿发散 我已经尝试过中所说的这个帖子 https stackoverflow com questions 29262824 r center color palette on 0 当我尝试手动创建颜色时 我得
  • 如何获得属于五分位数的x?

    我正在大学学习使用 R 进行计量经济学项目 所以请原谅我的笨拙 基本上 使用并给出 一个矩阵 股票价格 行 天 列 公司股票价格 另一个矩阵 市值 行 天 列 公司市值 我必须收集第三个矩阵每天观察的属于市值分布第一五分位数的股票价格 然后
  • 从 R 环境中删除对象

    我正在阅读 Hadley 的 Advanced R 在第 8 章中 他说我们可以使用以下方法从环境中删除对象 rm 但是 移除该物体后我仍然可以看到该物体 这是我的代码 e lt new env e a lt 1 e b lt 2 e a
  • 将 VLMC 拟合到很长的序列

    我正在尝试将 VLMC 拟合到最长序列为 296 个状态的数据集 我这样做如下所示 Load libraries library PST library RCurl library TraMineR Load and transform d

随机推荐