Reputation: 1328
My goal is to change variables data class
of uploaded dataset
. data class
should be selected by the user in ui
.
As uploaded datasets
might be different, I use lapply
to create selectInput
for each column in the dataset. Piece of code below generates selectInputs for each column called variable_i
, where i
is a number of column.
lapply(seq(ncol( rawdata() )),function(i){
selectInput(inputId = paste0("variable","_",i),label = colnames(rawdata())[i],
choices = c("factor", "numeric", "integer", "character"),
selected = class(rawdata()[,i])
)
})
Using this selectInput
user can input data class
.
My question is, how to change class of variables using inputed info from input$variable_i
as input names are dynamic and I can't simply call it.
Maybe is there any other approaches to change data class from UI?
Whole code I use below. If the problem will be solved, I'll share full working code.
library(summarytools)
library("shiny")
library("shinydashboard")
library("dplyr")
# Server ------------------------------------------------------------------
server <- function(input, output,session) {
#upload file from PC
rawdata <- reactive({
inFile <- input$fileIn
if (is.null(inFile))
return(NULL)
read.csv(inFile$datapath, sep=input$Separator)
})
#Get data example
output$DataCheck <- renderTable({
head(rawdata())
})
#get data summary
output$summaryTable <- renderUI({
out <- print(dfSummary( rawdata(),graph.magnif = 0.8), style = 'grid', omit.headings = TRUE, method = 'render',bootstrap.css = FALSE)
out[[3]][[2]][[1]]
})
output$colname_in <- renderUI({
selectInput(inputId = "colname",
label = "Choose column",
choices = c("",colnames(rawdata())),
selected = "")
})
observeEvent(input$change_class, {
v$data <- eval(parse(text = paste0('v$data %>% mutate(',
input$colname,
' = as.',
input$class,
'(',
input$colname,
'))')
)
)
})
}
# UI ----------------------------------------------------------------------
ui <- bootstrapPage(
dashboardPage(
dashboardHeader(title = "AK47"
), #dashboardHeader
#Sidebar--------------------------------------------------------------------------
dashboardSidebar(
sidebarMenu(
id = "tabs",
menuItem("Step 1: Input Data", tabName = "Input", icon = icon("cog"))
) #sidebarMenu
),#dashboardSidebar
#Body-------------------------------------------------------------------------------------
dashboardBody(
tabItems(
tabItem("Input",
fluidRow(
box(width = 4,title = 'Upload your data file:',solidHeader = T,status = 'primary',
#Upload file from PC
fileInput('fileIn',label = 'Select the data'),
#choose separator
radioButtons("Separator","Choose separator:", inline = TRUE,
choices=c(Comma=",",
Semicolon=";",
Tab="\t"), selected = ";")
) #box
), #fluidRiw
fluidRow(
box(width = 12,title = 'Check the data for correct separator:',solidHeader = F ,status = 'primary',
tableOutput('DataCheck'),
tags$hr()
) #box
), #fluidRow
fluidRow(
box(width = 12,title = 'Change variable typesr:',solidHeader = F ,status = 'primary',
uiOutput("colname_in"),
selectInput(inputId = "class",
label = "Choose class",
choices = c("", "factor", "numeric", "integer", "character"),
selected = ""),
actionButton("change_class",
"Change class"),
uiOutput('summaryTable'),
tags$hr()
) #box
) #fluidRow
) #tabItem
) #tabItems
)#dashboardBody
)#dashboardPage
)#bootstrapPage
shinyApp(ui, server)
Upvotes: 1
Views: 1138
Reputation: 18561
Instead of generating one selectInput
for each column, I would use two selectInputs
, one for column name, one for class and an action button to change the class.
Here is my approach. It might not be perfect, but could be a start.
library("shiny")
library("dplyr")
library("ggplot2")
shinyApp(
ui = fluidPage(
# Layout with sidebar
sidebarLayout(
## Sidebar -----
sidebarPanel(
# > some example input on sidebar -----
uiOutput("colname_in"),
selectInput(inputId = "class",
label = "Choose class",
choices = c("", "factor", "numeric", "integer", "character"),
selected = ""),
actionButton("change_class",
"Change class")
), # closes Sidebar-Panel
# Main-Panel ------
mainPanel(
tableOutput("print")
) # closes mainPanel
) # closes sidebarLayout
), # closes fluidPage
# Server ------
server = function(input, output, session){
v <- reactiveValues(data = iris)
output$colname_in <- renderUI({
selectInput(inputId = "colname",
label = "Choose column",
choices = c("",colnames(v$data)),
selected = "")
})
observeEvent(input$change_class, {
v$data <- eval(parse(text = paste0('v$data %>% mutate(',
input$colname,
' = as.',
input$class,
'(',
input$colname,
'))')
)
)
})
output$print <- renderTable({
print(input$colname)
print(input$class)
print(input$change_class)
v$data
})
} # Closes server
) # Closes ShinyApp
Update Below I integrated my approach into your code. It is important to read the csv into the reactiveValue v$data which works inside an observeEvent.
library("summarytools")
library("shiny")
library("shinydashboard")
library("dplyr")
# Server ------------------------------------------------------------------
server <- function(input, output,session) {
#upload file from PC
v = reactiveValues(path = NULL)
observeEvent(input$fileIn, {
req(input$fileIn)
v$data <- read.csv(input$fileIn$datapath, sep = input$Separator)
})
#Get data example
output$DataCheck <- renderTable({
req(v$data)
head(v$data)
})
#get data summary
output$summaryTable <- renderUI({
req(v$data)
out <- print(dfSummary(v$data,graph.magnif = 0.8), style = 'grid', omit.headings = TRUE, method = 'render',bootstrap.css = FALSE)
out[[3]][[2]][[1]]
})
output$colname_in <- renderUI({
req(v$data)
selectInput(inputId = "colname",
label = "Choose column",
choices = c("",colnames(v$data)),
selected = "")
})
observeEvent(input$change_class, {
v$data <- eval(parse(text = paste0('v$data %>% mutate(',
input$colname,
' = as.',
input$class,
'(',
input$colname,
'))')
)
)
})
}
# UI ----------------------------------------------------------------------
ui <- bootstrapPage(
dashboardPage(
dashboardHeader(title = "AK47"
), #dashboardHeader
#Sidebar--------------------------------------------------------------------------
dashboardSidebar(
sidebarMenu(
id = "tabs",
menuItem("Step 1: Input Data", tabName = "Input", icon = icon("cog"))
) #sidebarMenu
),#dashboardSidebar
#Body-------------------------------------------------------------------------------------
dashboardBody(
tabItems(
tabItem("Input",
fluidRow(
box(width = 4,title = 'Upload your data file:',solidHeader = T,status = 'primary',
#Upload file from PC
fileInput('fileIn',label = 'Select the data'),
#choose separator
radioButtons("Separator","Choose separator:", inline = TRUE,
choices=c(Comma=",",
Semicolon=";",
Tab="\t"), selected = ";")
) #box
), #fluidRiw
fluidRow(
box(width = 12,title = 'Check the data for correct separator:',solidHeader = F ,status = 'primary',
tableOutput('DataCheck'),
tags$hr()
) #box
), #fluidRow
fluidRow(
box(width = 12,title = 'Change variable typesr:',solidHeader = F ,status = 'primary',
uiOutput("colname_in"),
selectInput(inputId = "class",
label = "Choose class",
choices = c("", "factor", "numeric", "integer", "character"),
selected = ""),
actionButton("change_class",
"Change class"),
uiOutput('summaryTable'),
tags$hr()
) #box
) #fluidRow
) #tabItem
) #tabItems
)#dashboardBody
)#dashboardPage
)#bootstrapPage
shinyApp(ui, server)
Upvotes: 2