运行 R Shiny 应用程序时如何在数据表函数中编辑列名?

Posted

技术标签:

【中文标题】运行 R Shiny 应用程序时如何在数据表函数中编辑列名?【英文标题】:How to edit column names in datatable function when running R shiny app? 【发布时间】:2019-07-12 08:58:51 【问题描述】:

我在 R Shiny 中使用 DT 包中的数据表函数,我希望我的应用程序的用户可以编辑列名(变量名)。有什么选择吗?

现在我使用的是文本输入“old_var_name”、文本输入“new_var_name”和操作按钮“update_variable_name”。但在这一点上,我当时只能更改变量名。我希望用户能够更改他想要的变量名。

服务器:

tab <- eventReactive(input$import,
inFile <- input$file1
if (is.null(inFile))
  return(NULL)

tabledata <- read.xlsx(inFile$datapath,startRow=1,sheet = 1)
)

name_temp <- eventReactive(input$var_name,
if (input$old_name == "")
  colnames(tab())
 else 
    c(colnames(tab())[1:(which(colnames(tab()) == input$old_name)-1)],input$new_name,
    colnames(tab())[(which(colnames(tab()) == input$old_name)+1):length(colnames(tab()))])

)

final_rename <- reactive(
d <- tab()
colnames(d) <- name_temp()
d
)

output$tabledata <- DT::renderDataTable(
if (input$var_name == 0) 
  DT::datatable(tab(),editable = T)
 else 
  DT::datatable(final_rename(),editable = T)

)

用户界面:

tabPanel("Table",h1("Table",align="center") ,
actionButton(inputId = "import", label = "Import data"),br(),br(),                           
splitLayout(textInput(inputId = "old_name", label = "Old variable name"),                           
textInput(inputId = "new_name", label = "New variable Name")),
actionButton(inputId = "var_name", label = "Update Variable name"),br(),br(),
DT::dataTableOutput("tabledata"))

是否有任何建议可以实现这一点或任何我可以使用的数据表选项,然后用户将能够更改他想要的所有变量名称?

【问题讨论】:

查找data.table::setnames(),这种情况会更好。 非常感谢,这正是我想要的! 【参考方案1】:

这是一个带有上下文菜单的解决方案。右键单击列标题以对其进行编辑。完成后按“Escape”,或将鼠标移到文本输入框外。此解决方案不会干扰排序。

library(shiny)
library(DT)

callback <- c(
  "$.contextMenu(",
  "  selector: '#table th',", 
  "  trigger: 'right',",
  "  autoHide: true,",
  "  items: ",
  "    text: ",
  "      name: 'Enter column header:',", 
  "      type: 'text',", 
  "      value: ''", 
  "    ",
  "  ,",
  "  events: ",
  "    show: function(opt)",
  "      $.contextMenu.setInputValues(opt, text: opt.$trigger.text());",
  "    ,",
  "    hide: function(opt)",
  "      var $this = this;",
  "      var text = $.contextMenu.getInputValues(opt, $this.data()).text;",
  "      var $th = opt.$trigger;",
  "      $th.text(text);",
  "    ",
  "  ",
  ");" 
)

ui <- fluidPage(
  tags$head(
    tags$link(rel = "stylesheet", href = "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.8.0/jquery.contextMenu.min.css"),
    tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.8.0/jquery.contextMenu.min.js")
  ),
  DTOutput("table")
)

server <- function(input, output)
  output[["table"]] <- renderDT(
    datatable(iris[1:3,], callback = JS(callback))
  , server = FALSE)  


shinyApp(ui, server)

【讨论】:

您知道是否可以检索新列值以便在显示的数据集中更新它们?我试过这样做,但由于我对 JS 不是很熟悉,所以我失败了。谢谢! 我修改了隐藏时执行的函数,为:hide: function(opt) Shiny.onInputChange('oldColumnValue', opt.$trigger.text()) var $this = this; var text = $.contextMenu.getInputValues(opt, $this.data()).text; var $th = opt.$trigger; $th.text(text); Shiny.onInputChange('newColumnValue', text) 嗨 Stéphane - 您认为今天匹配 R 4.0 的 javascript 代码可能会发生变化吗? 此解决方案不再有效(至少在 R 4.1.0 下)。 @micsky 我刚刚尝试使用 R 4.1.0,它工作正常。【参考方案2】:

这是一种友好的方式,只是它会干扰排序。所以只有在禁用排序时才好。双击列标题进行编辑,然后按 Tab 退出。

library(DT)

callback <- c(
  "table.on('dblclick.dt', 'thead th', function(e) ",
  "  var $th = $(this);",
  "  var index = $th.index();",
  "  var colname = $th.text(), newcolname = colname;",
  "  var $input = $('<input type=\"text\">')",
  "  $input.val(colname);",
  "  $th.empty().append($input);",
  "  $input.on('change', function()",
  "    newcolname = $input.val();",
  "    if(newcolname != colname)",
  "      $(table.column(index).header()).text(newcolname);",
  "    ",
  "    $input.remove();",
  "  ).on('blur', function()",
  "    $(table.column(index).header()).text(newcolname);",
  "    $input.remove();",
  "  );",
  ");"
)

datatable(iris[1:3,], callback = JS(callback))

【讨论】:

感谢您的精彩回答!由于这在我的应用程序中有效,我如何将值写回 Shiny 应用程序(即将新列名保存在数据集中)?

以上是关于运行 R Shiny 应用程序时如何在数据表函数中编辑列名?的主要内容,如果未能解决你的问题,请参考以下文章

如何知道(或指定)R shiny 使用的 localhost 端口(在本地运行时)

R Shiny:如何从数据表中的自定义按钮调用 JavaScript 函数

如何在 r shiny 中使用 JS 数据表 API?

如何始终在 R Shiny 的 DataTables 中显示 3 位小数? [关闭]

如何在 Shiny 中引用 ui.R 中的反应元素

R Shiny:使用来自反应函数的数据制作反应图