使用 R Shiny 中的操作按钮将行从一个 DT 移动到其他 DT

2023-12-24

UPDATE

我正在尝试使用制作一个应用程序shiny and DT, 类似于此处 Shree 接受的答案 https://stackoverflow.com/questions/57853627/moveable-multiple-items-in-r-shiny-boxes-something-similar-to-attached-screens。我想对它进行以下补充:

  1. 从 Shree 扩展解决方案,以便来自DT左侧(源)的表格可以移动到右侧和后面的多个表格,并且可以扩展,这样我就可以决定要在右侧放置多少张表格。也就是说,左侧表格中的不同项目可以放入右侧不同的表格中。
  2. 此外,右侧每个表格旁边都有双箭头按钮,以便通过单击双箭头按钮可以添加或删除表格中的所有项目,而不仅仅是用于移动选定变量的单箭头按钮,像这儿 https://www.maprecord.com/CM_help/CM_fieldselection.html,但仍然可以决定是否显示它们。
  3. 即使右侧的表格为空,也可以看到。

有人可以帮忙解决这些问题吗?


正如已经提到的闪亮的模块 https://shiny.rstudio.com/articles/modules.html是解决这个问题的一种优雅的方法。你必须传递一些reactives用于接收行并且您必须返回一些reactives发送行/告诉主表它应该删除刚刚发送的行。

一个完整的工作示例如下所示:

library(shiny)
library(DT)

receiver_ui <- function(id, class) {
   ns <- NS(id)
   fluidRow(
      column(width = 1,
             actionButton(ns("add"), 
                          label = NULL,
                          icon("angle-right")),
             actionButton(ns("add_all"), 
                          label = NULL,
                          icon("angle-double-right")),
             actionButton(ns("remove"),
                          label = NULL,
                          icon("angle-left")),
             actionButton(ns("remove_all"),
                          label = NULL,
                          icon("angle-double-left"))),
      column(width = 11,
             dataTableOutput(ns("sink_table"))),
      class = class
   )
}

receiver_server <- function(input, output, session, selected_rows, full_page, blueprint) {
   ## data_exch contains 2 data.frames:
   ## send: the data.frame which should be sent back to the source
   ## receive: the data which should be added to this display
   data_exch <- reactiveValues(send    = blueprint,
                               receive = blueprint)
   
   ## trigger_delete is used to signal the source to delete the rows whihc just were sent
   trigger_delete <- reactiveValues(trigger = NULL, all = FALSE)
   
   ## render the table and remove .original_order, which is used to keep always the same order
   output$sink_table <- renderDataTable({
      dat <- data_exch$receive
      dat$.original_order <- NULL
      dat
   })
   
   ## helper function to move selected rows from this display back 
   ## to the source via data_exch
   shift_rows <- function(selector) {
      data_exch$send <- data_exch$receive[selector, , drop = FALSE]
      data_exch$receive <- data_exch$receive[-selector, , drop = FALSE]
   }
   
   ## helper function to add the relevant rows
   add_rows <- function(all) {
      rel_rows <- if(all) req(full_page()) else req(selected_rows())
      data_exch$receive <- rbind(data_exch$receive, rel_rows)
      data_exch$receive <- data_exch$receive[order(data_exch$receive$.original_order), ]
      ## trigger delete, such that the rows are deleted from the source
      old_value <- trigger_delete$trigger
      trigger_delete$trigger <- ifelse(is.null(old_value), 0, old_value) + 1
      trigger_delete$all <- all
   }
   
   observeEvent(input$add, {
      add_rows(FALSE)
   })
   
   observeEvent(input$add_all, {
      add_rows(TRUE)
   })
   
   observeEvent(input$remove, {
      shift_rows(req(input$sink_table_rows_selected))
   })
   
   observeEvent(input$remove_all, {
      shift_rows(req(input$sink_table_rows_current))
   })
   
   ## return the send reactive to signal the main app which rows to add back
   ## and the delete trigger to remove rows
   list(send   = reactive(data_exch$send),
        delete = trigger_delete)
}


ui <- fluidPage(
   tags$head(tags$style(HTML(".odd {background: #DDEBF7;}",
                             ".even {background: #BDD7EE;}",
                             ".btn-default {min-width:38.25px;}",
                             ".row {padding-top: 15px;}"))),
   fluidRow(
      actionButton("add", "Add Table") 
   ),
   fluidRow(
      column(width = 6, dataTableOutput("source_table")),
      column(width = 6, div(id = "container")),
   )
)

server <- function(input, output, session) {
   orig_data <- mtcars
   orig_data$.original_order <- seq(1, NROW(orig_data), 1)
   my_data <- reactiveVal(orig_data)
   
   handlers <- reactiveVal(list())
   
   selected_rows <- reactive({
      my_data()[req(input$source_table_rows_selected), , drop = FALSE]
   })
   
   all_rows <- reactive({
      my_data()[req(input$source_table_rows_current), , drop = FALSE]
   })
   
   observeEvent(input$add, {
      old_handles <- handlers()
      n <- length(old_handles) + 1
      uid <- paste0("row", n)
      insertUI("#container", ui = receiver_ui(uid, ifelse(n %% 2, "odd", "even")))
      new_handle <- callModule(
         receiver_server,
         uid,
         selected_rows = selected_rows,
         full_page = all_rows,
         ## select 0 rows data.frame to get the structure
         blueprint = orig_data[0, ])
      
      observeEvent(new_handle$delete$trigger, {
         if (new_handle$delete$all) {
            selection <- req(input$source_table_rows_current)
         } else {
            selection <- req(input$source_table_rows_selected)
         }
         my_data(my_data()[-selection, , drop = FALSE])
      })
      
      observe({
         req(NROW(new_handle$send()) > 0)
         dat <- rbind(isolate(my_data()), new_handle$send())
         my_data(dat[order(dat$.original_order), ])
      })
      handlers(c(old_handles, setNames(list(new_handle), uid)))
   })
   
   output$source_table <- renderDataTable({
      dat <- my_data()
      dat$.original_order <- NULL
      dat
   })
}


shinyApp(ui, server)

解释

模块包含 UI 和服务器,并且由于命名空间技术,名称只需要在一个模块内是唯一的(并且每个模块以后也必须有一个唯一的名称)。该模块可以通过以下方式与主应用程序通信reactives哪些被传递到callModule(请注意,我仍在使用旧函数,因为我尚未更新我的闪亮库),或者从服务器函数返回的函数。

在主应用程序中,我们有一个按钮,它动态插入 UI 并调用callModule来激活逻辑。observers也在同一调用中生成以使服务器逻辑工作。

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

使用 R Shiny 中的操作按钮将行从一个 DT 移动到其他 DT 的相关文章

  • R中添加水印

    我在用magickR中的库 我想在一些图片上添加水印 I used image annotate功能如下 img lt image read C Users Maydin Desktop manzara png image annotate
  • 将命名参数列表传递给函数?

    我想编写一个小函数来从适当的分布生成样本 例如 makeSample lt function n dist params values lt makeSample 100 unif list min 0 max 10 values lt m
  • ggplot2可以在一个图例中分别控制点大小和线大小(线宽)吗?

    一个使用的例子ggplot2绘制数据点组和连接每组均值的线 并使用相同的映射aes for shape并为linetype p lt ggplot mtcars aes gear mpg shape factor cyl linetype
  • 将 Instagram/youtube 嵌入 Shiny R 应用程序

    我想通过点击图表来播放 Instagram 或 Youtube 视频 例如显示异常值等 到目前为止 明确告诉 Shiny 视频内容是有效的 require shiny require ggplot2 data df lt data fram
  • R 中具有稳健回归的异常值

    我正在使用lmrobR 中的函数使用robustbase用于稳健回归的库 我会把它用作 rob reg lt lmrob y 0 dat method MM control a1 当我想返回我使用的摘要时summary rob reg 稳健
  • LDA with topicmodels,如何查看不同文档属于哪些主题?

    我正在使用 topicmodels 包中的 LDA 我已经在大约 30 000 个文档上运行它 获取了 30 个主题 并获得了主题的前 10 个单词 它们看起来非常好 但我想看看哪些文档属于哪个主题的概率最高 我该怎么做 myCorpus
  • kableExtra 中的 row_spec() 函数不会在 html 输出中创建水平线

    我想在 kableextra 表中的某一行下方添加一条水平线 row spec 函数的参数 hline after 应该在行下方添加水平线 row spec 文档 https www rdocumentation org packages
  • 如何在for循环中引用变量?

    我正在循环访问不同的 data tables 和 data table 中的变量 但我在引用内部变量时遇到问题for loop dt1 lt data table a1 c 1 2 3 a2 c 4 5 2 dt2 lt data tabl
  • 计算每个唯一值出现的次数

    假设我有 v rep c 1 2 2 2 25 现在 我想计算每个唯一值出现的次数 unique v 返回唯一值是什么 但不返回它们的数量 gt unique v 1 1 2 我想要一些能给我的东西 length v v 1 1 25 le
  • 如何从 Fortran 调用 R 函数?

    根据http gallery rcpp org articles r function from c http gallery rcpp org articles r function from c Rcpp 允许用户从 C 调用 R 函数
  • 我无法下载 R 中的 reshape2 包 [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我在尝试安装 R 包时收到此响应 gt installed packages reshape2 Package LibPath V
  • 正则表达式字符串中第一个和最后一个非点的位置

    我希望找到字符串的第一个和最后一个非点元素的位置 理想情况下我想这样做regex在基地R 我已经写过R解决问题的代码 不过 我对一个感兴趣regex解决方案 感谢您的任何建议 这是一个示例数据集和R代码以获得所需的结果 此代码拆分字符串并使
  • 纵向序列数据的三次样条方法?

    我有一个串行数据 格式如下 time milk Animal ID 30 25 6 1 31 27 2 1 32 24 4 1 33 17 4 1 34 33 6 1 35 25 4 1 33 29 4 2 34 25 4 2 35 24
  • 使用 purrr 迭代替换数据帧列中的字符串

    我想用purrr使用以下命令在数据框列上迭代运行多个字符串替换gsub 功能 这是示例数据框 df lt data frame Year 2019 Text c rep a aa 5 rep a bb 3 rep a cc 2 gt df
  • 如何计算R中移动窗口内的平均斜率

    我的数据集包含2个变量y 和 t 05s y 每 05 秒测量一次 我正在尝试计算移动中的平均坡度20秒窗口 即计算第一个 20 秒斜率值后 窗口向前移动一个时间单位 05 秒 并计算下一个 20 秒窗口 在以下位置生成连续 20 秒斜率值
  • 如何使用 R 计算成为列表中中位数的概率?

    假设我有以下数据集 其中显示了假设实验的每个状态的三个观察结果的列表 state lt c Iowa Minnesota Illinois outcome lt list c 5 11 11 c 3 12 8 c 9 14 2 dat lt
  • 将绘图调用拆分为多个块

    我正在编写一个图的解释 其中我基本上将在第一个块中创建图 然后描述该输出 并在第二个块中添加一个轴 然而 似乎每个块都会强制一个新的绘图环境 因此当我们尝试使用以下命令运行块时会出现错误axis独自的 观察 output html docu
  • 以引用透明的方式从函数的省略号参数中提取符号

    事情又发生了 我正要按下发布答案按钮的问题被删除了 我正在寻找一种方法来从函数的省略号参数中提取绑定到符号的对象的值以及符号 也就是说 我试图以引用透明的方式从省略号中提取符号 我尝试过使用替代品和lazy dots 但没有成功 funct
  • 更改闪亮 R 中的默认浏览器

    我在 RStudio 中使用 01 hello 虽然在 IE 中默认打开程序时它不会显示直方图 但即使在 Chrome 中 滑块也不起作用 我无法滑动条形图并看到直方图中的变化 如何更改 R 中的默认浏览器 以便闪亮启动 Chrome 而不
  • 文本挖掘 pdf 文件/词频问题

    我正在尝试挖掘一篇具有丰富 pdf 编码和图表的文章的 pdf 我注意到 当我挖掘一些 pdf 文档时 我得到的高频词是 phi taeoe toe sigma gamma 等 它与某些 pdf 文档配合良好 但与其他文档配合使用时却得到这

随机推荐