Reputation: 25
Shiny app loads a .csv with fileInput() but can't change it afterwords.
I want to change (multiply by (-1)) one of the columns of the dataframe within the app with a button after identifying the column
The object loadedData is a read.csv() function that outputs a dataframe that I use in the remainder of the app I've tried changing the object directly, through functions, be it it's reactive data or a static copy that try to override later but can't seem to make the change permanent.
#--------------UI side
#import data
sidebarLayout(
sidebarPanel(
fileInput('main', 'Input file', multiple = FALSE,
accept =".csv"),
checkboxInput("header", "Header", TRUE),
radioButtons("sep", "Separator",
choices = c(Comma = ",",
Semicolon = ";",
Tab = "\t"),
selected = ","),
radioButtons("quote", "Quote",
choices = c(None = "",
"Double Quote" = '"',
"Single Quote" = "'"),
selected = '"')
),
#--------------Server Side
# read dataset
loadedData <- reactive({
read.csv(
input$main$datapath,
header = input$header,
sep = input$sep,
quote = input$quote
)
})
# change signal
observeEvent(input$main, {
output$advancedsignalchange <- renderUI({
tagList(
selectInput('signalchangecolumn', 'Signal Change Column', choices = names(loadedData())),
actionButton('signalchange','Submit signal change')
)
})
})
observeEvent(input$signalchange,{
print(loadedData)
print(names(loadedData()))
aa <- as.array(input$signalchangecolumn)
print(loadedData()[aa][[1]][1]) #token value before change
#loadedData()[aa] <- loadedData()[aa] *-1 ## can't override
print(loadedData()[aa] *-1) #change
print(loadedData()[aa][[1]][1]) #token value after change
})
2 errors here: If I uncomment this line in an attempt to override loadedData()
loadedData()[aa] <- loadedData()[aa] *-1
Warning: Error in <-: invalid (NULL) left side of assignment
similarly if I try
loadedData[aa] <- loadedData()[aa] *-1
Warning: Error in <-: object of type 'closure' is not subsettable
so I can't save the change
the print statements are a way to validate the syntax so, say I had a column where the 1st value is "1", output would be,
1
-1 (along with the rest of the column)
1
therefore the syntax itself for the change operation is viable but I can't override the column on the imported dataframe
Upvotes: 1
Views: 1171
Reputation: 2505
To store and update reactive objects, you can use reactiveVal
or reactiveValues
instead of reactive
.
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("main", "Input file",
multiple = FALSE,
accept = ".csv"
),
checkboxInput("header", "Header", TRUE),
radioButtons("sep", "Separator",
choices = c(
Comma = ",",
Semicolon = ";",
Tab = "\t"
),
selected = ","
),
radioButtons("quote", "Quote",
choices = c(
None = "",
"Double Quote" = '"',
"Single Quote" = "'"
),
selected = '"'
)
),
mainPanel(
uiOutput("advancedsignalchange"),
dataTableOutput("data")
)
)
)
server <- function(input, output, session) {
loadedData <- reactiveVal() # create reactive val
observe({
req(input$main$datapath) # make sure variable isn't empty
loadedData(read.csv( # initialize reactiveVal
input$main$datapath,
header = input$header,
sep = input$sep,
quote = input$quote))
})
observeEvent(input$main, {
output$advancedsignalchange <- renderUI({
tagList(
selectInput("signalchangecolumn", "Signal Change Column", choices = names(loadedData())),
actionButton("signalchange", "Submit signal change")
)
})
})
observeEvent(input$signalchange, {
aa <- as.array(input$signalchangecolumn)
tmp <- loadedData()
tmp[aa] <- tmp[aa] * -1
loadedData(tmp) # update reactiveVal
})
output$data <- renderDataTable(loadedData()) # display data
}
shinyApp(ui, server)
Upvotes: 1