Shiny - ObserveEvent and actionButton adding a column to table
Asked Answered
F

1

0

I would like to do the following tasks:

  1. I want to add a column to a rendered table with observeEvent and via action button. Initially, the table should be displayed as uploaded by the user and mutated (column added) by the action button trigger. Note that in this code, the user chooses which column will provide the reference values for the added column (in this example, the max value of a user selected variable).

An important note is that the resulting table (with recently added column) should be available for future data manipulations which take place in a tab not displayed here.

  1. Also, would it be possible to hide the rendered table every time selection input is changed?

Appreciate any help!

library(shiny)
library(shinydashboard)
library(tidyverse)
library(data.table)


upload_tab <-     tabItem(tabName = "FileUpload",
                          titlePanel("Uploading Files"),
                          sidebarPanel(
                            fileInput('file1', 'Choose file to upload',
                                      accept = c('text/csv',
                                                 'text/comma-separated-values',
                                                 'text/tab-separated-values',
                                                 'text/plain','.csv','.tsv')),
                            checkboxInput("header", "Header", TRUE),
                            radioButtons("sep", "Separator",
                                         choices = c(Comma = ",",
                                                     Semicolon = ";",
                                                     Tab = "\t"),
                                         selected = ","),
                            radioButtons("quote", "Quote",
                                         choices = c(None = "",
                                                     "Double Quote" = '"',
                                                     "Single Quote" = "'"),
                                         selected = '"')),
                          mainPanel(
                            DT::dataTableOutput('contents')
                          )
)

splitter_tab <- tabItem(
  tabName = "Splitter",
  fluidPage(
    box(title = "Split means and letters into two separate columns", width = 3, solidHeader = T, status = "primary",
        selectInput("get_let_mean",'Select column:',choices = NULL),
        br(),
        actionButton("splitter", "Split")),
    mainPanel(
      DT::dataTableOutput('contents1')
    )
  )
)

sideBar_content <- dashboardSidebar(
  sidebarMenu(
    menuItem("Upload File", tabName = "FileUpload"),
    menuItem("Splitter", tabName = "Splitter")
  )
)

body_content <- dashboardBody(
  tabItems(
    upload_tab,
    splitter_tab
  )
)

ui <-  dashboardPage(
  dashboardHeader(title = "Test"),
  ## Sidebar content
  sideBar_content,
  ## Body content
  body_content,
  ## Aesthetic
  skin = "blue"
)

server <- function(input, output,session) {
  
  
  data<-reactive({
    if(is.null(input$file1))
      return()
    inFile <- input$file1
    df <- read.csv(inFile$datapath,
                   header = input$header,
                   sep = input$sep,
                   quote = input$quote)
  }) 
  
  
  output$contents <- DT::renderDataTable({
    DT::datatable(data(),
                  options = list(
                    "pageLength" = 40))
  })
  
  observe({
    value <- names(data())
    updateSelectInput(session,"get_let_mean", choices = value)
  })
  
  observeEvent(input$splitter,{
    d1 <- data() %>% 
      mutate(clean_values=max(.data[[input$get_let_mean]]))
    data(d1)
  })
  
  
  output$contents1 <- DT::renderDataTable({
    DT::datatable(data(),
                  options = list("pageLength" = 40))
  })
  
  
}

shinyApp(ui, server)

File example:

file<-c(structure(list(trial_id = c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 4L, 4L, 4L, 4L, 4L, 4L
), factor_A = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 
12L, 13L, 14L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 6L), replicates = c(3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 5L, 5L, 5L, 
5L, 5L, 4L, 4L, 4L, 4L, 4L, 4L), means = c(57.5, 22.5, 17.5, 
25, 5, 2, 3, 2, 12.5, 25, 3, 2.8, 1, 0.5, 64.1, 80.7, 83, 84.4, 
83.7, 25, 20, 25, 26, 27, 28), letters = c("a", "b", "bc", "b", 
"de", "e", "e", "e", "cd", "d", "e", "e", "e", "e", "a", "b", 
"b", "b", "b", "a", "b", "a", "a", "a", "a")), class = "data.frame", row.names = c(NA, 
-25L)))
Firstnighter answered 28/2, 2022 at 22:25 Comment(4)
your question is not clear. Adding a column is not an issue. Your code is adding two columns. However, you are using get_values() and get_letters(). It is not clear what you are trying to achieve. Also, are you trying to split a single column into two? Your sample data does not show such sample records to split.Decontaminate
My bad, I copied the original code. I have now instead of "get_values" and "get_letters", "max" returning the max of a column. I get an error, no trace available.Firstnighter
As max() will give a single value, do you want to repeat that single maximum value for 25 records in your sample data?Decontaminate
Yes. But I believe it if you use y + 1, it would work the same way.Firstnighter
D
1

Perhaps you are looking for this

library(shiny)
library(shinydashboard)
library(tidyverse)
library(data.table)
library(DT)


upload_tab <-     tabItem(tabName = "FileUpload",
                          titlePanel("Uploading Files"),
                          sidebarPanel(
                            fileInput('file1', 'Choose file to upload',
                                      accept = c('text/csv',
                                                 'text/comma-separated-values',
                                                 'text/tab-separated-values',
                                                 'text/plain','.csv','.tsv')),
                            checkboxInput("header", "Header", TRUE),
                            radioButtons("sep", "Separator",
                                         choices = c(Comma = ",",
                                                     Semicolon = ";",
                                                     Tab = "\t"),
                                         selected = ","),
                            radioButtons("quote", "Quote",
                                         choices = c(None = "",
                                                     "Double Quote" = '"',
                                                     "Single Quote" = "'"),
                                         selected = '"')),
                          mainPanel(
                            DT::dataTableOutput('contents')
                          )
)

splitter_tab <- tabItem(
  tabName = "Splitter",
  fluidPage(
    box(title = "Split means and letters into two separate columns", width = 3, solidHeader = T, status = "primary",
        selectInput("get_let_mean",'Select column:',choices = NULL),
        br(),
        actionButton("splitter", "Split")),
    mainPanel(
      DT::dataTableOutput('contents1')
    )
  )
)

sideBar_content <- dashboardSidebar(
  sidebarMenu(
    menuItem("Upload File", tabName = "FileUpload"),
    menuItem("Splitter", tabName = "Splitter")
  )
)

body_content <- dashboardBody(
  tabItems(
    upload_tab,
    splitter_tab
  )
)

ui <-  dashboardPage(
  dashboardHeader(title = "Test"),
  ## Sidebar content
  sideBar_content,
  ## Body content
  body_content,
  ## Aesthetic
  skin = "blue"
)

server <- function(input, output,session) {
  rv <- reactiveValues(df=NULL)
  
  data<-reactive({
    if(is.null(input$file1))
      return()
    inFile <- input$file1
    df <- read.csv(inFile$datapath,
                   header = input$header,
                   sep = input$sep,
                   quote = input$quote)
  }) 
  
  
  output$contents <- DT::renderDataTable({
    DT::datatable(data(),
                  options = list(
                    "pageLength" = 40))
  })
  
  observe({
    value <- names(data())
    updateSelectInput(session,"get_let_mean", choices = value)
  })
  
  observeEvent(input$file1,{
    rv$df <- data()
  })
  
  
  observeEvent(input$splitter,{
    rv$df <- rv$df %>% 
      mutate(clean_values= max(.data[[input$get_let_mean]]))
    
  })
  
  
  output$contents1 <- DT::renderDataTable({
    DT::datatable(rv$df,
                  options = list("pageLength" = 40))
  })
  
}

shinyApp(ui, server)
Decontaminate answered 1/3, 2022 at 20:26 Comment(1)
Exactly. I actually was able to get it like an hour ago and the solution was here "rv$df <- rv$df", like you wrote. Appreciate the help!Firstnighter

© 2022 - 2024 — McMap. All rights reserved.