Home > database >  Select the column name of a reactive dataframe and update it with a textInput()
Select the column name of a reactive dataframe and update it with a textInput()

Time:03-30

In the shiny app below I upload a dataset,so its a reactive dataset, and then I get a selectInput() with its column names. Then I should be able to select a column and change it with the textInput() after hitting the actionButton().

library(shiny)
library(shinydashboard)
library(DT)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(
    fileInput("file1", "Choose CSV File",
              accept = c(
                "text/csv",
                "text/comma-separated-values,text/plain",
                ".csv")
    ),
    uiOutput("column"),
    textInput("text", label = "Set column name", placeholder = "Enter text..."),
    actionButton("sub","submit")
  ),
  dashboardBody(
    
    dataTableOutput("process")
  )
)

server <- function(input, output) {
  raw<-reactive({
    
    inFile <- input$file1
    
    if (is.null(inFile))
      return(NULL)
    
    read.csv(inFile$datapath, header = T)
  })
  
  output$column<-renderUI({
    selectInput("col","Pick a column to change its name",
                choices = colnames(raw()))
  })
  mydf <- reactiveValues(df = raw(), names = names(raw()))
  
  observeEvent(input$sub, {
    req(input$text)
    mydf$names[mydf$names == input$col] <- input$text
    names(mydf$df) <- mydf$names
    updateSelectInput(inputId = "col", choices = mydf$names)
  })
  output$process<-renderDataTable({
    mydf$df
  })
}

shinyApp(ui, server)    

CodePudding user response:

I took your line:

mydf <- reactiveValues(df = raw(), names = names(raw()))

And replaced it with:

  mydf <- reactiveValues(df = NULL, names = NULL)
  
  observeEvent(raw(), {
    if(!is.null(raw())) {
      mydf$df <- raw()
      mydf$names <- names(raw())
    }
  })

And for me it functions as how I think you wanted it. The primary issue is it would crash for me upon start. As you wrote it, it tries to access raw() immediately and put it in the reactiveValues. Thus, by making the reactiveValues NULL by default, and then only adding it in when raw() exists, it seems to work perfectly.

CodePudding user response:

Here is one possible approach. Maybe there are better options. Just replace iris with your input data. It should work.

A general advice is to avoid function names as object names for reactive objects, such as raw() which is a function, but also the name of a reactive in your example. It makes things more difficult to debug and it will throw error messages which don't make sense, if you forget that raw() is also a function.

library(shiny)
library(shinydashboard)
library(DT)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(
    # fileInput("file1", "Choose CSV File",
    #           accept = c(
    #             "text/csv",
    #             "text/comma-separated-values,text/plain",
    #             ".csv")
    # ),
    uiOutput("column"),
    textInput("text", label = "Set column name", placeholder = "Enter text..."),
    actionButton("sub","submit")
  ),
  dashboardBody(
    
    dataTableOutput("process")
  )
)

server <- function(input, output) {
  
  mydf <- reactiveValues(names = NULL)
  
  raw_df <- reactive({
    
    mydat <- iris # here goes the input file
    
    iris_nms <- mydf$names
    
    if(!is.null(iris_nms)) {
      names(mydat) <- iris_nms
    }
    
    mydat
  })
  
  output$column <- renderUI({
    selectInput("col","Pick a column to change its name",
                choices = colnames(raw_df()))
  })
  
  observeEvent(input$sub, {
    req(input$text)
    org_names <- names(raw_df())
    org_names[org_names == input$col] <- input$text
    mydf$names <- org_names

  })

  output$process<-renderDataTable({
    raw_df()
  })
}

shinyApp(ui, server)    
  • Related