sunitprasad1 sunitprasad1 - 2 months ago 15
R Question

How to dynamically rename multiple columns in R Shiny based on drop down inputs?

I have a shiny app like shown below :

require(shiny)
require(dplyr)
server <- function(input, output) {

dataa <- reactive({
table1 <- mtcars
return(table1)
})

output$contents <- renderDataTable({
dataa()
})

output$mpg <- renderUI({
selectizeInput(
'MPG', 'MPG: ', choices = c("",as.list(colnames(dataa()))),
options = list(
placeholder = 'Please select',
onInitialize = I('function() { this.setValue(""); }')
)
)
})

output$cyl <- renderUI({
selectizeInput(
'CYL', 'CYL: ', choices = c("",as.list(colnames(dataa()))),
options = list(
placeholder = 'Please select',
onInitialize = I('function() { this.setValue(""); }')
)
)
})


DataRename <- reactive({
Data <- dataa()
DataNew1<-Data
MPG <- input$MPG
CYL <- input$CYL
if(!is.null(MPG)){
StatRenameEmp1 <- paste0("DataNew1 <- dplyr::rename(DataNew1,Mileage=",MPG,")")
eval(parse(text=StatRenameEmp1))
} else{
DataNew1<-Data
}
if(!is.null(CYL)){
StatRenameEmp1 <- paste0("DataNew1 <- dplyr::rename(DataNew1,Cylinders=",CYL,")")
eval(parse(text=StatRenameEmp1))
}else{
DataNew1<-Data
}

return(DataNew1)
})

output$rename <- renderDataTable({
DataRename()
})


}

ui <- shinyUI({
navbarPage("Dynamic Rename",
tabPanel("Data",
fluidPage(
titlePanel("mtcars"),

dataTableOutput('contents'))
),
tabPanel("Variables",
fluidPage(
sidebarLayout(
sidebarPanel(
uiOutput("mpg"),
uiOutput("cyl")
),
mainPanel(
dataTableOutput("rename")
)
)
)
)


)



})

shinyApp(ui = ui, server = server)


The aim is to rename the columns of the dataframe (mtcars) where I have some standard names given to the final data and the user is supposed to select the corresponding variable from the input dataset. Eg., I want to rename a certain column selected by the user (
mpg
in this case) as "Mileage",
cyl
to "Cylinder" and so on.

My problem is I am not able to rename multiple columns at a go. Only the first column is being renamed not the remaining.

Second, I may not select any column, in that case the column name need not be changed, i.e., if MPG is not selected then it should remain as
mpg


How do I get all the columns renamed according to a name set by me, based on the user inputs?

The renaming works good if I select all dropdowns.

Answer

Why not simple ?

colnames(df)[which(colnames(df)=="mpg")]="New name"

Or may be i not understands your aims...

Shiny example

require(shiny)
require(dplyr)
server <-  function(input, output) {

  dataa <- reactive({
    table1 <- mtcars
    return(table1)
  })

  output$contents <- renderDataTable({
    dataa()      
  })

  output$mpg <- renderUI({
    selectizeInput(
      'MPG', 'MPG: ', choices = c("",as.list(colnames(dataa()))),
      options = list(
        placeholder = 'Please select',
        onInitialize = I('function() { this.setValue(""); }')
      )
    )
  })   

  output$cyl <- renderUI({
    selectizeInput(
      'CYL', 'CYL: ', choices = c("",as.list(colnames(dataa()))),
      options = list(
        placeholder = 'Please select',
        onInitialize = I('function() { this.setValue(""); }')
      )
    )
  })  


  DataRename <- reactive({
    Data <- dataa()
    DataNew1<-Data
    MPG <- input$MPG
    CYL <- input$CYL

    if(!is.null(MPG)){
      colnames(DataNew1)[which(colnames(DataNew1)==MPG)]="Mileage"
    }

    if(!is.null(CYL)){
      colnames(DataNew1)[which(colnames(DataNew1)==CYL)]="Cylinders"
    }

    return(DataNew1)
  })

  output$rename <- renderDataTable({
    DataRename()      
  })


}

ui <- shinyUI({
  navbarPage("Dynamic Rename",
             tabPanel("Data",
                      fluidPage(
                        titlePanel("mtcars"),

                        dataTableOutput('contents'))
             ),
             tabPanel("Variables",
                      fluidPage(
                        sidebarLayout(
                          sidebarPanel(
                            uiOutput("mpg"),
                            uiOutput("cyl")
                          ),
                          mainPanel(
                            dataTableOutput("rename")
                          )
                        )
                      )
             )


  )



})

shinyApp(ui = ui, server = server)

Or if you want use text input to rename colums you can do it in such way

require(shiny)
require(dplyr)
server <-  function(input, output) {

  dataa <- reactive({
    table1 <- mtcars
    return(table1)
  })

  output$contents <- renderDataTable({
    dataa()      
  })

  output$renamer <- renderUI({
    lapply(colnames(dataa()),function(i){
      textInput(paste0("col_",i),i,i)
    })
  })  


  DataRename <- reactive({
    Data <- dataa()
    DataNew1<-Data

    for ( i in names(input) ){

      if(grepl(pattern = "col_",i)){
        colnames(DataNew1)[which(colnames(DataNew1)==substr(i,5,nchar(i)))]=input[[i]]
      }

    }

    return(DataNew1)
  })

  output$rename <- renderDataTable({
    DataRename()      
  })


}

ui <- shinyUI({
  navbarPage("Dynamic Rename",
             tabPanel("Data",
                      fluidPage(
                        titlePanel("mtcars"),

                        dataTableOutput('contents'))
             ),
             tabPanel("Variables",
                      fluidPage(
                        sidebarLayout(
                          sidebarPanel(

                            uiOutput("renamer")
                          ),
                          mainPanel(
                            dataTableOutput("rename")
                          )
                        )
                      )
             )


  )



})

shinyApp(ui = ui, server = server)
Comments