title: r shiny - apply function to reactive data table
body: <p>I would like to be able to apply a user defined function to the set of columns chosen via <code>pickerInput</code>.  I am unsure if I need an <code>actionButton</code> or not.  </p>
  
  <p>My code is below</p>
  
  <pre><code>X &lt;- c("plyr", "dplyr", "tm", "readxl", "wordcloud", "SnowballC", "stringdist", "tidytext",
     "rmarkdown", "knitr", "quanteda", "reshape", "stringr", "RecordLinkage", 
     "data.table", "rvest", "qdap", "shiny", "shinydashboard", "shinyWidgets", "DT") 
  
  lapply(X, FUN = function(X){
  do.call("library", list(X))
  })
  
  ###### BUILD REQUIRED FUNCTIONS TO CLEAN DATA ########
  
  removeSPE &lt;- function(x) gsub("[[:punct:]]", "", x)
  
  cleanup &lt;- function(x){
     x &lt;- as.character(x) # convert to character
    x &lt;- tolower(x) # make all lowercase
    x &lt;- sapply(x, removeSPE) # remove special characters
    x &lt;- trimws(x, "both") # since stopwords have been removed, there is extra white space left, this removes it
    x &lt;- gsub("(?&lt;=\\b\\w)\\s(?=\\w\\b)", "", x, perl = TRUE) # removes whitespace btwn two single chars
    return(x)
  }
  </code></pre>
  
  <p><strong><em>UI</em></strong></p>
  
  <pre><code>##### APP BEGINS HERE WITH UI #####
  
  ui &lt;- dashboardPage(
  dashboardHeader(title = "Record Linkage App"),
  dashboardSidebar(
      sidebarMenu(
          ## Tab 1 -- Specify Task
          menuItem("Select Task And Upload Files", tabName = "task", icon = icon("file-text-o")),
          ## Tab 2 -- View Raw Data Files
          menuItem("View Raw Data", tabName = "raw", icon = icon("file-excel")),
          ## Tab 3 -- View Processed Data Files
          menuItem("View Processed Data", tabName = "processed", icon = icon("file-excel")),
          ## Tab 4 -- Select Training Set
          menuItem("Select Training Set", tabName = "mltrain", icon = icon("file-text-o")),
          ## Tab 5 -- View Weight &amp; Probabilities (choose which chart to view or both?)
          menuItem("Visualize Distributions", tabName = "distributions", icon = icon("bar-chart-o")),
          ## Tab 6 -- View Results (review, match and trash files--need to be able to choose dataset)
          ## Want to be able to add checkboxes to select rows for inclusion in deletion later on
          menuItem("View Result Files", tabName = "fileview", icon = icon("file-text-o"))
  
      )), # close dashboard sidebar
  
  #### Dashboard Body starts here
  
  dashboardBody(
      tabItems(
          ### Specify Task &amp; Upload Files Tab
          tabItem(tabName = "task",
                  radioButtons("task", "Select a Task:", c("Frame Deduplication", "Frame Record Linkage")),
                  fileInput("selection", "Upload Files:", multiple = T, 
                            accept = c(".xlsx", ".xls", "text/csv", "text/comma-separated-values, text/plain", ".csv")),
                  helpText(paste("Please upload a file.  Supported file types are:  .txt, .csv and .xls.")),
                  br(),
                  helpText(paste("Note:  Record Linkage requires two data frames."))
  
          ), # close first tabItem
  
          tabItem(tabName = "raw",
                  helpText(paste("This tab displays the raw, unprocessed data frames selected in the previous tab.")),
                  helpText(paste("Select the columns you wish to display.  These columns will be used for string comparisons")),
                  fluidRow(
                      column(width = 6,
                             uiOutput("pick_col1"),
                             dataTableOutput("content1")
                      ),
                      column(width = 6,
                             uiOutput("pick_col2"),
                             dataTableOutput("content2")
                      )
                  )
  
          ), # close second tabItem
  
          tabItem(tabName = "processed",
                  helpText(paste("This tab displays the processed data frames you saw in the previous tab.")),
                  br(),
                  helpText(paste("All data fields are now uniform and free of punctuation or special characters etc.")),
                  actionButton("clean1", "Clean data from table 1"),
                  actionbutton("clean2", "Clean data from table 2"),
                  fluidRow(
                      column(width = 6,
                             uiOutput("clean_tbl1"),
                             dataTableOutput("clean_content1")
                      ),
                      column(width = 6,
                             uiOutput("clean_tbl2"),
                             dataTableOutput("clean_content1")
                      )
                  )
  
          ) # close third tabItem
      ) # close tabItems
  ) # close dashboardBody 
  ) # closes dashboardpage
  
  options(shiny.maxRequestSize = 100*1024^2)
  </code></pre>
  
  <p><strong><em>SERVER</em></strong></p>
  
  <pre><code>server &lt;- function(input, output, session) {
  
  data &lt;- reactiveValues(file1 = NULL,
                         file2 = NULL)
  
  observe({
      if (!is.null(input$selection$datapath[1]))
  
          if (grepl(".csv$", input$selection$datapath[1])) {
  
              data$file1 &lt;- read.csv(input$selection$datapath[1], header = TRUE, sep = ",")
  
          } else if (grepl(".xls$|.xlsx$", input$selection$datapath[1])) {
  
              data$file1 &lt;- read_excel(input$selection$datapath[1], col_names = TRUE)    
          } 
  })
  
  observe({
      if (!is.null(input$selection$datapath[2]))
  
          if (grepl(".csv$", input$selection$datapath[2])) {
  
              data$file2 &lt;- read.csv(input$selection$datapath[2], header = TRUE, sep = ",")
  
          } else if (grepl(".xls$|.xlsx$", input$selection$datapath[2])) {
  
              data$file2 &lt;- read_excel(input$selection$datapath[2], col_names = TRUE)    
          } 
  })
  
  output$pick_col1 &lt;- renderUI({
  
      pickerInput(
          inputId = "pick_col1",
          label = "Select the columns of table 1 you wish to display:",
          choices = colnames(data$file1),
          selected = colnames(data$file1),
          options = list(`actions-box` = TRUE,
                         `selected-text-format` = paste0("count &gt; ", length(colnames(data$file1)) - 1),
                         `count-selected-text` = "Alle",
                         liveSearch = TRUE,
                         liveSearchPlaceholder = TRUE),   # build buttons for collective selection
          multiple = TRUE)
  })
  
  output$pick_col2 &lt;- renderUI({
  
      pickerInput(
          inputId = "pick_col2",
          label = "Select the columns of table 2 you wish to display:",
          choices = colnames(data$file2),
          selected = colnames(data$file2),
          options = list(`actions-box` = TRUE,
                         `selected-text-format` = paste0("count &gt; ", length(colnames(data$file2)) - 1),
                         `count-selected-text` = "Alle",
                         liveSearch = TRUE,
                         liveSearchPlaceholder = TRUE),   # build buttons for collective selection
          multiple = TRUE)
  })
  
  
  
  output$content1 &lt;- renderDataTable({
  
      data$file1[, req(input$pick_col1)]
  
  
  })
  
  output$content2 &lt;- renderDataTable({
  
      data$file2[, req(input$pick_col2)]
  
  })
  
  
  # here we want to take the columns selected and apply our 
  # pre defined functions:  sweet, etc. to make the data unform and easier to analyze.
  
  observeEvent(input$clean1, {
  
      output$clean_content1 &lt;- renderDataTable({
          cleanup(selection)
  
  
      })
  
  })
  
  observeEvent(input$clean2, {
  
      output$clean_content2 &lt;- renderDataTable({
          cleanup(selection)
  
      })
  
  })
  }
  
  shinyApp(ui, server)
  </code></pre>
  
  <p>My question is:</p>
  
  <ol>
  <li>How can I apply a function <code>cleanup</code> defined above to the set of columns selected in the <code>pickerInput</code>?</li>
  <li>Is an <code>actionButton</code> the best way to do so?</li>
  <li>If I need to use the data I passed through the <code>cleanup</code> function, does making the datatable reactive inefficient?</li>
  </ol>
  
  <p>Any help would be much appreciated.</p>