Ricardo Ricardo - 2 months ago 32
R Question

R Shiny: Create a button that updates a data.frame

I have a randomly generated data.frame. The user can modify a slider to choose the number of points. Then I plot this data.frame.

I want to add a button than when clicked, it performs a modification in the previous randomly generated data.frame (but without regenerating the data.frame). The modification is a voronoid relaxation, and it should be performed once per each time the button is clicked and the graph generated.

Until now, I have not achieved anything similar...

ui.R

library(shiny)

# Define UI for application that draws a histogram
shinyUI(fluidPage(

# Application title
titlePanel("Map Generator:"),

# Sidebar with a slider input for the number of bins
sidebarLayout(
sidebarPanel(
p("Select the power p to generate 2^p points."),
sliderInput("NumPoints",
"Number of points:",
min = 1,
max = 10,
value = 9),
actionButton("GenPoints", "Generate"),
actionButton("LloydAlg", "Relaxe")
),

# Show a plot of the generated distribution
mainPanel(



plotOutput("distPlot",height = 700, width = "auto")
)
)
))


server.R

library(shiny)
library(deldir)

shinyServer(function(input, output) {


observeEvent(input$NumPoints,{

x = data.frame(X = runif(2^input$NumPoints,1,1E6),
Y = runif(2^input$NumPoints,1,1E6))

observeEvent(input$LloydAlg, {
x = tile.centroids(tile.list(deldir(x)))
})

output$distPlot <- renderPlot({
plot(x,pch = 20,asp=1,xlim=c(0,1E6),ylim = c(0,1E6))
})

})
})


Of course there is something that I must be doing wrong, but I am quite new into shiny I can't figure it out what I am doing wrong...

GyD GyD
Answer

This should work (even though I am pretty sure this could be improved):

shinyServer(function(input, output) {
  library(deldir)  

  data = data.frame(
    X = runif(2^9, 1, 1E6),
    Y = runif(2^9, 1, 1E6)
  )

  rv <- reactiveValues(x = data)

  observeEvent(input$GenPoints, {
    rv$x <- data.frame(
      X = runif(2^input$NumPoints,1,1E6),
      Y = runif(2^input$NumPoints,1,1E6)
    )
  })
  observeEvent(input$LloydAlg, {
    rv$x = tile.centroids(tile.list(deldir(rv$x)))
  })

  output$distPlot <- renderPlot({
    plot(rv$x,pch = 20,asp=1,xlim=c(0,1E6),ylim = c(0,1E6))
  })
})

So first I initialize the points to plot. I use runif(2^9, 1, 1E6) because the starting value of the sliderInput is 9 all the time.

I also removed the observeEvent from the sliderInput and moved it to the GenPoints actionButton.

Comments