R Shiny not plotting at all - r

I'm new to shiny and I'm trying to use it for a simulation of a prey/predator model.
First, I wanted to generate the dataframe with all the initial positions for each animal; and try to plot it usign ggplot; but when I hit the actionButton, the plot never showed. I dont interstand why and there is any error message to let me at least know what is wrong.
Here is the code:
library(shiny)
library(tidyverse)
library(ggplot2)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("nPrey", "select total number of preys", 1, 100, 10, 1),
sliderInput("nHunter", "select total number of Hunters", 1, 100, 10, 1),
actionButton ("play", "Begin simulation")
),
mainPanel(
plotOutput("plot")
)
)
)
server <- function(input, output, session) {
zMax = 20
simulation <- eventReactive(input$play, {
createInitialTable(input$nPrey, input$nHunter)
})
output$plot <- renderPlot({
p <- ggplot() +
geom_point(aes_string(x="X",y="Y"), data=simulation()) +
coord_cartesian(xlim =c(0, zMax), ylim = c(0, zMax))
})
createInitialTable <- function (nPrey, nHunter){
aAnimal <- data.frame()
cVar <- c("X", "Y")
for (i in 1:nPrey){
aAnimal <- rbind(aAnimal, c(round(runif(1)*zMax), round(runif(1)*zMax)))
}
for (i in 1:nHunter){
aAnimal <- rbind(aAnimal, c(round(runif(1)*zMax), round(runif(1)*zMax)))
}
colnames(aAnimal) <- cVar
return (aAnimal)
}
}
shinyApp(ui, server)
Thank you for reading this

Simple fix: Remove p <- and you should be good to go. However, to improve you need to check the reactivity of your execution when the nPrey and Hunter are dynamically changing.

Related

how to design a reactive visualization graph for a time series using shiny?

I want to design a reactive interaction graph for a time series for shiny.
It is used for when I have a time series. I change the first point of the time series.
Then I can get the reactive graph changed for the point changed.
I have trouble for how to assign the value input into the function. Specifically, for the
yinput<-sensi(num). I want to the input be some number range from 0.1 to 0.9.but my sensitive's
function only allow to enter one input.
Is there any idea for that?
Thanks
library(ggplot2)
sensi<-function(input)
{
y<-c(input,5,12,21,30,50,90,100)
return(y)
}
Date = c("2020/07/16","2020/07/23","2020/07/30","2020/08/06","2020/08/13","2020/08/20","2020/08/27","2020/09/13")
num<-c(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9)
yinput<-sensi(num)
df <- data.frame(yinput, Date = as.Date(Date))
ui <- fluidPage(
titlePanel(title=h4("plot1", align="center")),
sidebarPanel(
sliderInput("num", "Number:",min = 0, max = 0.9,value=0.5)),
mainPanel(plotOutput("plot2")))
server <- function(input,output){
dat <- reactive({
test <- df[df$num %in% seq(from=min(input$num),to=max(input$num),by=1),]
print(test)
test
})
output$plot2<-renderPlot({
ggplot(df) + aes(Date, y) + geom_line()})}
shinyApp(ui, server)
Here's a very basic example
You should be doing your 'thinking' inside your 'server' function.
Hopefully this example will show you how reactive inputs and outputs relate to each other, and you can extend it to your plot.
require(shiny)
ui <- fluidPage(
sliderInput("num", "Number:", min = 0.1, max = 0.9, value = 0.5),
textOutput("number_display")
)
server <- function(input, output){
output$number_display <-
renderText({
as.character(input$num)
})
}
shinyApp(ui = ui, server = server)
Where I've said as.character(input$num), you'll want to do something with num to make your plot.

Display table and recompute one column based on sliders

I want to create a small shiny app to explore a scoring function that I am writing for a set of data observations. This is my first shiny app so bear with me.
What I want to show is the data table where one column is computed by a function (let's say f(x) = x^2 + y) where x is another (numeric) column in the table and y should be adjustable with a slider in the sidebar.
I want to make the table reactive, so that as soon as the slider is adjusted, the content that is displayed will be updated. Does anyone have a link to a tutorial (I could not find a similar problem) or a suggestion how to handle this. If so, please let me know!
This is the code I have so far:
library(shiny)
#### INIT ####
x <- 1
y <- 0.5
z <- 2
df <- data.frame(
a=1:10,
b=10:1
)
df['score'] <- df[,x]^y + z
#### UI ####
ui <- fluidPage(
title = "Examples of DataTables",
sidebarLayout(
sidebarPanel(
sliderInput("x", "x:",
min = 0, max = ncol(df),
value = 1),
sliderInput("y", "y:",
min = 1, max = 10,
value = 1),
sliderInput("z", "z:",
min = 1, max = 100,
value = 20)
),
mainPanel(
tabsetPanel(
id = 'dataset',
tabPanel("df", dataTableOutput("df"))
)
)
)
)
#### SERVER ####
server <- function(input, output) {
sliderValues <- reactive({
df['score'] <- df[,input$x]^input$y + input$z
})
sliderValues()
output$df<- renderDataTable(df)
}
#### RUN ####
shinyApp(ui = ui, server = server)
Just make the data.frame you actually plot reactive. For example
server <- function(input, output) {
calcualtedValues <- reactive({
df['score'] <- df[,input$x]^input$y + input$z
df
})
output$df<- renderDataTable(calcualtedValues())
}
Here the calcualtedValues reactive element returns a new data.frame when the input is updated, and then you actually render that updated data.frame rather than the original data.frame each time.

Guess the correlation - Is there an R function in shiny to show the next plot? data collection with shiny

I want to show three different scatterplots with a next button. the task is to guess the strength of the correlation in each plot. the problem is that I can only see the same plot. I try to work with a next button to see the next plot.
library(shiny)
# 3 different dataframes/data for scatter plots
data1 <- data.frame(a <- c(20,30,35,45,50,60,80),
b <- c(60,70,72,77,82,88,90))
data2 <- data.frame(a <- c(20,30,35,45,50,60,80),
b <- c(60,70,68,77,82,88,70))
data3 <- data.frame(a <- c(35,40,38,50,52,51,30),
b <- c(60,70,72,64,82,88,90))
ui = fluidPage(
sidebarPanel(
sliderInput
(inputId = "fit", label = "estimated correlation",
min = 0, max = 1, value = 0),
actionButton("newplot", "next")),
mainPanel(plotOutput("plot")))
server = function(input, output) {
output$plot <- renderPlot({
input$newplot
plot(data1)
plot(data2)
plot(data3)
})
}
shinyApp(ui = ui, server = server)
I don't believe there is any built in way to do this, but you could easily keep a variable to track which plot you want to show and then use switch() to draw just that plot. For example
cycle <- function(x, max) {
if(x() < max) {
x(x() + 1)
} else {
x(1)
}
}
server <- function(input, output) {
index <- reactiveVal(1)
observeEvent(input$newplot, {
cycle(index, 3)
})
output$plot <- renderPlot({
switch(index(),
plot(data1),
plot(data2),
plot(data3)
)
})
}
Here I just wrote the cycle helper function to make it easier to loop back to 1 when increment the index. But basically it's just taking a value 1 to 3. Then in the renderPlot, it looks a the current index and only draws that plot.

How do I animate my R Shiny plot's output based on the increments of slider input value?

I've looked through R Shiny tutorials and stackoverflow for answers related to my query. I usually wait for 3-4 days to solve a coding problem before I attempt to post.
I have an animated slider in my UI that loops through time interval in a column (column a) . I'm trying to produce an animated line plot that plots y values of another column (column b), corresponding to the nrow() of that time interval. The slider works perfectly, but I haven't been able to plot the output.
I mightve missed some concepts related to reactivity in Shiny app. Appreciate any guidance I can get related to my query. I'll be happy to post more info if needed.
a <- c(0,1,2,3,4,5,6)
b <- c(50,100,40,30,20,80)
mydata <- cbind(a,b)
mydata <- as.data.frame(mydata())
ui <- fluidPage (
headerPanel("basic app"),
sidebarPanel(
sliderInput("slider",
label = "Time elapsed",
min = 0,
max = nrow(mydata()),
value = 1, step = 1,
animate =
animationOptions(interval = 200, loop = TRUE))
),
mainPanel(
plotlyOutput("plot")
)
)
server <- function(input, output) {
sliderValues <- reactive({
data.frame(
Name = "slider",
Value = input$slider)
})
output$plot <- renderPlot({
x<- as.numeric(input$slider)
y <- as.numeric(b[x])
ggplot(mydata,aes_string(x,y))+ geom_line()
})
}
Just as a demo, I wanted the animated plot to come out like this, but in correspondance to UI slider values :
library(gganimate)
library(ggplot2)
fake <- c(1,10)
goods <- c(11,20)
fakegoods <- cbind(fake,goods)
fakegoods <- data.frame(fakegoods)
ggplot(fakegoods, aes(fake, goods)) + geom_line() + transition_reveal(1, fake)
Does this accomplish what you are looking for? Note that I removed the first element, 0, from vector a as your original example had more elements in a than b, and in order for them to be cbind together they must be the same length.
library(ggplot2)
library(shiny)
a <- c(1,2,3,4,5,6)
b <- c(50,100,40,30,20,80)
mydata <- cbind(a,b)
mydata <- as.data.frame(mydata)
ui <- fluidPage (
headerPanel("basic app"),
sidebarPanel(
sliderInput("slider",
label = "Time elapsed",
min = min(mydata$a),
max = max(mydata$a),
value = min(mydata$a), step = 1,
animate =
animationOptions(interval = 200, loop = TRUE))
),
mainPanel(
plotOutput("plot")
)
)
server <- function(input, output) {
output$plot <- renderPlot({
plotdata <- mydata[1:which(input$slider==mydata$a),]
p <- ggplot(plotdata,aes(x = a,y = b))
if(nrow(plotdata)==1) {
p + geom_point()
} else {
p + geom_line()
}
})
}

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...
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.

Resources