0

I Want to edit table column names in shiny and save it for further analysis.

I have added a piece of code which allows me to edit the colnames in the table. Please see the example below.

With this simple example here. I can edit the column names by double clicking them. But I don't know how to save the edited table for further data analysis in shiny. For instance save the edited table in the edit action button.

Thanks a lot for your help.


library(shiny)
library(DT)

callback <- c(
  "var colnames = table.columns().header().to$().map(function(){return this.innerHTML;}).get();",
  "Shiny.onInputChange('colnames', colnames);",
  "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);",
  "      colnames[index] = newcolname;",
  "      Shiny.onInputChange('colnames', colnames);",
  "    }",
  "    $input.remove();",
  "  }).on('blur', function(){",
  "    $(table.column(index).header()).text(newcolname);",
  "    $input.remove();",
  "  });",
  "});"
)

ui <- fluidPage(
  
  titlePanel("Need your help"),
  
  DTOutput("table"), 
  
  DTOutput("editedTable"),
  
  actionButton("save", label = "save")
)

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

shinyApp(ui, server)

Wang
  • 1,314
  • 14
  • 21

1 Answers1

1

This JavaScript code sends the column names to input$colnames. You can do:

server <- function(input, output){

  dataset <- iris[1:3, ]

  Dat <- reactiveVal(dataset)

  observeEvent(input$colnames, {
    Dat(setNames(Dat(), input$colnames))
  })

  output$table <- renderDT({
    datatable(dataset, callback = JS(callback))
  }, server = FALSE)  
  
}

With this code, the reactive value Dat() is the dataset with the edited column names.

Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • Hi @Stéphane Laurent, Thanks a lot for your kind help. For some reason I got the following error running your code, and I don't know how to solve it. Could you please help me out? Thanks. `Error in <-: 'names' attribute [6] must be the same length as the vector [5]` – Wang May 08 '21 at 14:02
  • @Wang That's probably because `input$colnames` includes the name of the column of row names, at the first position. Try `setNames(Dat(), input$colnames[-1])`. – Stéphane Laurent May 08 '21 at 14:10
  • Thank you very much for your prompt reply and help! It is working now. I can edit the table, but the edited output does not show any changes with the following code. `output$editedTable <- renderDT({ datatable(Dat())}, server = FALSE) `. I am so sorry to keeps bothering you. – Wang May 08 '21 at 14:33
  • @Wang Strange, that should work. But why do you want to render the edited table? It will have no difference. – Stéphane Laurent May 08 '21 at 15:01
  • I render the edited table because I want to test if it works. – Wang May 08 '21 at 16:23
  • @ Stéphane Laurent, it works now. I made a mistake. Thanks a lot for your help! – Wang May 08 '21 at 16:47