Reputation: 45
I'm using R shiny in combination with ggplot to visualize a certain dataset. I want the user to be able to add values to this dataset. I can get my application so far as to show me the original data + one data point, but as soon as the user enters a new point, the old one is gone: the user-input data is not actually stored in my dataframe.
Some of the code I'm using (changed variable names for simplicity):
shinyServer(
function(input, output) {
output$newPlot <- renderPlot({
input$addButton
isolate({
x <- as.numeric(input$x)
y <- as.numeric(input$y)
if (!is.na(y)) {
data <- rbind(data, data.frame(x = x, y = y))
# more code here
}
# more code here
plot <- myPlot(data)
print(plot)
})
})
}
)
The user can give values for x and y with textInput
and then submit those values with a button (actionButton
). Each time the user hits 'add', the most recently inputted values for x and y are shown on top of the original data, but any other values the user inputted (in the same session) are lost. How do I get shiny to remember my users inputs and plot all of it?
Upvotes: 2
Views: 3661
Reputation: 19970
I cannot reproduce yours specifically given the code you provided but perhaps an example will help you. The part you need is reactiveValues
, this allows you to store your dataset and update it throughout the session as you see fit. Perhaps this can help you fix your problem?
require(shiny)
data(iris)
runApp(
list(
ui = fluidPage(
headerPanel('Adding Data'),
sidebarPanel(
textInput("species", label="Add a new species", value="Enter species"),
numericInput("sepal.length", label="Add a new sepal length", value=""),
numericInput("sepal.width", label="Add a new speal width", value=""),
numericInput("petal.length", label="Add a new petal length", value=""),
numericInput("petal.width", label="Add a new petal width", value=""),
actionButton("addButton", "UPLOAD!")
),
mainPanel(
tableOutput("table"))
),
server = function(input, output) {
# just a small part of iris for display
iris_sample <- iris[sample(nrow(iris), 10),]
row.names(iris_sample) <- NULL
# The important part of reactiveValues()
values <- reactiveValues()
values$df <- iris_sample
observe({
# your action button condition
if(input$addButton > 0) {
# create the new line to be added from your inputs
newLine <- isolate(c(input$sepal.length, input$sepal.width, input$petal.length, input$petal.width, input$species))
# update your data
# note the unlist of newLine, this prevents a bothersome warning message that the rbind will return regarding rownames because of using isolate.
isolate(values$df <- rbind(as.matrix(values$df), unlist(newLine)))
}
})
output$table <- renderTable({values$df}, include.rownames=F)
}
)
)
Upvotes: 4