I have the shiny
app below in which Im displaying all the column names of the initial
dataframe as well as their class()
in a table.
What I want to do is select a a column and after pressing the actionButton()
to convert it to numeric
. In this case lets choose case_id
.
The new dataset is initial2
but it has to be available for use even if we convert one of its variables to numeric
or not. How can I do this?
Also the Class in the table with the classes for case_id
should be converted from character
to numeric
after pressing the actionButton()
The dataframe may be diffrent every time.
## app.R ##
library(shiny)
library(shinydashboard)
library(DT)
library(tibble)
library(tidyverse) # for the tibble
initial<-structure(list(case_id = c("3397364", "3397364"), action = c("3397364-RAAMELK",
"3397364-RAAMELK"), resource = c("RAAMELK", "RAAMELK"), lifecycle = c(1,
1), registration_type = structure(1:2, .Label = c("start", "complete"
), class = "factor"), timestamp = structure(c(1667523600, 1667531220
), tzone = "UTC", class = c("POSIXct", "POSIXt")), activity = c("RAAMELK",
"RAAMELK"), activity_description = c("Forbrukt r<e5>melk", "Forbrukt r<e5>melk"
), ...9 = c(NA, NA), product = c("K101152", "K101152"), product_type_text = c("200100 - Milk",
"200100 - Milk"), qty = c(NA, 31), in_out = c("in", "out"), qty_scrap = c(NA_real_,
NA_real_), `FP ordre` = c(NA_character_, NA_character_), Artikkeltype = c("SF",
"SF"), .order = 1:2), row.names = c(NA, -2L), class = c("eventlog",
"log", "tbl_df", "tbl", "data.frame"), case_id = "case_id", activity_id = "activity", activity_instance_id = "action", lifecycle_id = "registration_type", resource_id = "resource", timestamp = "timestamp")
shinyApp(
ui = dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
dataTableOutput("dt0"),
dataTableOutput("dt"),
selectInput("cols","Select column to convert",choices = colnames(initial),multiple = F,selected =colnames(initial)[1] ),
actionButton("conv","Convert to numeric")
)
),
server = function(input, output, session) { # add session so we can update
initial<-reactive({
validate(
need(!is.null(input$file1), 'No data exists, please upload a csv')
)
# p<-read.csv(inFile$datapath, header = T,sep =
#input$separator,na.strings=c("",".","NA"))
})
output$dt0<-renderDataTable({
datatable(initial)
})
output$dt<-renderDataTable({
dat<-data.frame(tibble(Name = colnames(initial), Class = sapply(initial, function(x)
paste(class(x), collapse=", "))))
datatable(dat)
})
initial2<-reactive({input$conv
initial #after processing or not
})
}
)
CodePudding user response:
One option would be to use a reactiveVal
which you could init with your initial
dataset. The reactiveVal
could then be in your renderDataTable
and be updated via an observeEvent
triggered by the actionButton
. For the conversion I use lapply
which allows to convert multiple cols at once if desired.
library(shiny)
library(shinydashboard)
library(DT)
library(tibble)
library(tidyverse)
shinyApp(
ui = dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
dataTableOutput("dt0"),
dataTableOutput("dt"),
selectInput("cols", "Select column to convert", choices = colnames(initial), multiple = F, selected = colnames(initial)[1]),
actionButton("conv", "Convert to numeric")
)
),
server = function(input, output, session) { # add session so we can update
dat <- reactiveVal(initial)
output$dt0 <- renderDataTable({
datatable(dat())
})
output$dt <- renderDataTable({
dat <- data.frame(tibble(Name = colnames(dat()), Class = sapply(dat(), function(x) {
paste(class(x), collapse = ", ")
})))
datatable(dat)
})
observeEvent(input$conv, {
x <- dat()
x[input$cols] <- lapply(x[input$cols], as.numeric)
dat(x)
})
}
)
EDIT One option would be to init the reactiveVal
as an empty data frame. Then use e.g. an observeEvent
to uplaod your data and to init the reactiveVal
with the uploaded data. As an example I added a fileInput
to your app:
shinyApp(
ui = dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
fileInput("upload", "Upload a file"),
dataTableOutput("dt0"),
dataTableOutput("dt"),
selectInput("cols", "Select column to convert", choices = NULL, multiple = F),
actionButton("conv", "Convert to numeric")
)
),
server = function(input, output, session) { # add session so we can update
dat <- reactiveVal(data.frame())
observeEvent(input$upload, {
dat(read.csv(input$upload$datapath))
updateSelectInput(inputId = "cols", choices = colnames(dat()), selected = colnames(dat())[[1]])
})
output$dt0 <- renderDataTable({
datatable(dat())
})
output$dt <- renderDataTable({
dat <- data.frame(tibble(Name = colnames(dat()), Class = sapply(dat(), function(x) {
paste(class(x), collapse = ", ")
})))
datatable(dat)
})
observeEvent(input$conv, {
x <- dat()
x[input$cols] <- lapply(x[input$cols], as.numeric)
dat(x)
})
}
)