This is my reproducible example :
#http://gekkoquant.com/2012/05/26/neural-networks-with-r-simple-example/
library("neuralnet")
require(ggplot2)
setwd(dirname(rstudioapi::getSourceEditorContext()$path))
#Going to create a neural network to perform sqare rooting
#Type ?neuralnet for more information on the neuralnet library
#Generate 50 random numbers uniformly distributed between 0 and 100
#And store them as a dataframe
traininginput <- as.data.frame(runif(50, min=0, max=100))
trainingoutput <- sqrt(traininginput)
#Column bind the data into one variable
trainingdata <- cbind(traininginput,trainingoutput)
colnames(trainingdata) <- c("Input","Output")
#Train the neural network
net.sqrt <- neuralnet(Output~Input,trainingdata, hidden=c(input$w, input$b), threshold=0.01)
print(net.sqrt)
#Plot the neural network
plot(net.sqrt)
#Test the neural network on some test data
testdata <- as.data.frame((1:13)^2) #Generate some squared numbers
net.results <- predict(net.sqrt, testdata) #Run them through the neural network
#Lets see what properties net.sqrt has
class(net.results)
#Lets see the results
print(net.results)
#Lets display a better version of the results
cleanoutput <- cbind(testdata,sqrt(testdata),
as.data.frame(net.results))
colnames(cleanoutput) <- c("Input","ExpectedOutput","NeuralNetOutput")
head(cleanoutput)
lm1<- lm(NeuralNetOutput~ ExpectedOutput, data = cleanoutput)
ggplot(data = cleanoutput, aes(x= ExpectedOutput, y= NeuralNetOutput)) + geom_point() +
geom_abline(intercept = 0, slope = 1
, color="brown", size=0.5)
And this is the code I tried in shiny :
library(shiny)
library("neuralnet")
require(ggplot2)
ui <- fluidPage(
fluidRow(
column(width = 12, class = "well",
h4("Neural Network Plot"),
plotOutput("main_plot"),
hr(),
numericInput(inputId = "w",
label = "Weight(w):",
value = 5),
numericInput(inputId = "b",
label = "Biased(b):",
value = 5),
actionButton("update", "Update View"))))
#--------------------------------------------------------------------------------------------
server <- function(input, output) {
output$main_plot <- renderPlot({
traininginput <- as.data.frame(runif(50, min=0, max=100))
trainingoutput <- sqrt(traininginput)
trainingdata <- cbind(traininginput,trainingoutput)
colnames(trainingdata) <- c("Input","Output")
net.sqrt <- neuralnet(Output~Input,trainingdata, hidden=c(input$w, input$b), threshold=0.01)
print(net.sqrt)
plot(net.sqrt)
testdata <- as.data.frame((1:13)^2) #Generate some squared numbers
net.results <- predict(net.sqrt, testdata) #Run them through the neural network
class(net.results)
print(net.results)
cleanoutput <- cbind(testdata,sqrt(testdata),
as.data.frame(net.results))
colnames(cleanoutput) <- c("Input","ExpectedOutput","NeuralNetOutput")
head(cleanoutput)
lm1<- lm(NeuralNetOutput~ ExpectedOutput, data = cleanoutput)
ggplot(data = cleanoutput, aes(x= ExpectedOutput, y= NeuralNetOutput)) + geom_point() +
geom_abline(intercept = 0, slope = 1
, color="brown", size=0.5)})}
shinyApp(ui,server)
I wish to add an actionButton that really works so that I can Update my view instead of let it update automatically. What should I put inside my server.R ?
In the line 20 of the reproducible example, the variable w and bis the values I wish to control in the shiny server.
And is there a better to present my script? As I am quite new to shiny, I hope I can get some little guide/hints from anyone of you..
See the documentation example for the actionButton, specifically how isolate is being used there. This is the code from the example for posterity:
ui <- fluidPage(
sliderInput("obs", "Number of observations", 0, 1000, 500),
actionButton("goButton", "Go!"),
plotOutput("distPlot")
)
server <- function(input, output) {
output$distPlot <- renderPlot({
# Take a dependency on input$goButton. This will run once initially,
# because the value changes from NULL to 0.
input$goButton
# Use isolate() to avoid dependency on input$obs
dist <- isolate(rnorm(input$obs))
hist(dist)
})
}
Normally when you would move slider, shiny would update the histogram "continuously". As you isolate this variable, it waits on a button press.
Related
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.
I am using Shiny and R to visualize my data interactively. I would like to draw an interactive scatter plot of Petal.Width versus Petal.Length in Iris dataset and cluster the points based on k clusters (user input) and p, the percentage of data rows dedicated to the training dataset (user input). I added a hover feature to the scatterplot so that by clicking on each point, the whole dataset for that point will be demonstrated.
The output should look like this:
# Loading Libraries
library(shiny)
library(caret)
library(ggplot2)
data(iris)
ui <- pageWithSidebar(
headerPanel("Clustering iris Data"),
sidebarPanel(
sliderInput("k", "Number of clusters:",
min = 1, max = 5, value = 3),
sliderInput("prob", "Training percentage:",
min=0.5, max=0.9, value = 0.7)),
mainPanel(
# img(src='iris_types.jpg', align = "center", height="50%", width="50%"),
plotOutput("plot1", click = "plot_click"),
verbatimTextOutput("info")
)
)
server <- function(input, output) {
inTrain <- createDataPartition(y=iris$Species,
p=input$prob,
list=FALSE)
training <- iris[ inTrain,]
testing <- iris[-inTrain,]
kMeans1 <- kmeans(subset(training,
select=-c(Species)),
centers=input$k)
training$clusters <- as.factor(kMeans1$cluster)
output$plot1 <- renderPlot({
qplot(Petal.Width,
Petal.Length,
colour = clusters,
data = training,
xlab="Petal Width",
ylab="Petal Length")
})
output$info <- renderPrint({
# With ggplot2, no need to tell it what the x and y variables are.
# threshold: set max distance, in pixels
# maxpoints: maximum number of rows to return
# addDist: add column with distance, in pixels
nearPoints(iris, input$plot_click, threshold = 10, maxpoints = 1,
addDist = FALSE)
})
}
shinyApp(ui, server)
When I run the app in R Studio, I receive the following error:
Error in .getReactiveEnvironment()$currentContext() :
Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)
As mentioned by #Clemsang you are using reactives values outside an oberserver/render* function.
What you want to do is to create a reactive environment, where you use your inputs. That is, something which gets recalculated whenever the inputs change. Thus, you need to wrap your training calculation in reactive and when you want to use it in your render function, you "call" it by adding (). I like to name my reactives with a verb, to highlight the fact that I actually do something when these functions are called, hence the name get_training_data:
server <- function(input, output) {
get_training_data <- reactive({ ## now your inputs are in a reactive environment
inTrain <- createDataPartition(y=iris$Species,
p=input$prob,
list=FALSE)
training <- iris[ inTrain,]
testing <- iris[-inTrain,]
kMeans1 <- kmeans(subset(training,
select=-c(Species)),
centers=input$k)
training$clusters <- as.factor(kMeans1$cluster)
training
})
output$plot1 <- renderPlot({
qplot(Petal.Width,
Petal.Length,
colour = clusters,
data = get_training_data(),
xlab="Petal Width",
ylab="Petal Length")
})
output$info <- renderPrint({
# With ggplot2, no need to tell it what the x and y variables are.
# threshold: set max distance, in pixels
# maxpoints: maximum number of rows to return
# addDist: add column with distance, in pixels
nearPoints(iris, input$plot_click, threshold = 10, maxpoints = 1,
addDist = FALSE)
})
}
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()
}
})
}
Edited: I removed to the call to get a dataset from data.world and instead fed in the mtcars dataset which produces the same error of contrasts can only be applied to factors of 2 or more
I am learning shiny and wanted to create a plot that gives the linear regression line for both a) the whole plot and b) linear regression line for brushed points on the plot. I would even settle for just showing the summary stats for the regression of the brushed points.
The code below
plots the user inputs for x and y
allows the user to brush points
creates a reactive datasubset of brushed points
shows summary of the regression for all points
shows data table of the reactive datasubset of brushed points when a brush is applied
breaks down when asked to perform a regression on those brushed points for reasons I do not understand...
code:
library(shiny)
library(ggplot2)
library(data.world)
library(dplyr)
library(tidyverse)
library(DT)
#show data from data.world
gcdata_ds <- "https://data.world/llawsonwork/gcdata"
#gcdatafile <- data.world::query(
#qry_sql("SELECT * FROM gcdataclean"),
#dataset =gcdata_ds
#)
#datafile <- gcdatafile
#so that you will not need data.world
datafile <-mtcars
# Define UI for application that draws a histogram
ui <- fluidPage(
#Application Layout
sidebarLayout(
#Inputs
sidebarPanel(
#select variable for y-axis
selectInput(inputId = "ya",
label = "Y-axis",
choices = colnames(datafile),
selected = "life_expec"
),
#Select Variable for x axis
selectInput(inputId = "xa",
label = "X-axis",
choices = colnames(datafile),
selected = "life_expec"
)
),
#output
mainPanel(
plotOutput(outputId = "guilfordplot", brush = "plot_brush"),
htmlOutput(outputId = "summary"), # summary of lin regress all points
dataTableOutput(outputId = "brushedtracts"), # data table to make sure brushed points are updating correctly
textOutput(outputId = "brushedreg") # NOT Working summary of lin reg brushed points
)
)
)
#define server function
server <- function(input, output){
#this was useful in creating the regression model as X was always column 1 and Y was always column in this dataframe
datasubset <- reactive({
req(input$xa)
req(input$ya)
data.frame(X = datafile[input$xa], Y = datafile[input$ya])
})
#create datasubset of the brushed points
brushedsubset <- reactive({
req(input$xa)
req(input$ya)
req(input$plot_brush)
brushedPoints(datafile, brush = input$plot_brush) %>%
select(input$xa, input$ya)
})
#Create plot
output$guilfordplot <- renderPlot({
ggplot(data = datafile, aes_string(x = input$xa, y = input$ya)) +
geom_point() + geom_smooth(method = "lm")
})
#create summary file
output$summary <- renderUI({
model = lm(datasubset()[,2] ~ datasubset()[,1], data = datasubset())
r2 = format(summary(model)$r.squared, digits = 3)
txt = paste("The equation of the line is :\nY = ",
round(coefficients(model)[1],0), " + ",
round(coefficients(model)[2], 5), "X")
# str_3 <- format(coef(m)[1], digits = 3)
str_1 <- txt
str_2 <- paste("The R^2 value is equal to ", r2)
HTML(paste(str_1, str_2, sep = '<br/>'))
})
# create data table
output$brushedtracts <- DT::renderDataTable({
select(brushedsubset(), input$xa, input$ya)
})
# create brushed summary stats
output$brushedreg <- renderText({
modelbrush = lm(brushedsubset()[,2] ~ brushedsubset()[,1], data = brushedsubset())
br2 = format(summary(modelbrush)$r.squared, digits = 3)
btxt = paste("The equation of the line is :\nY = ",
round(coefficients(modelbrush)[1],0), " + ",
round(coefficients(modelbrush)[2], 5), "X")
paste(btxt, ' and the rsquared is: ', br2 )
})
}
# Run the application
shinyApp(ui = ui, server = server)
So the code above works for the summary regression of all points for a given x and y input.
But this code does not work for giving me the linear regression of the brushed points and I cannot figure out why because it is the nearly identical for the code for the linear regression of all points.
Any help would be appreciated and it there is a tidyer way of doing the linear regression and summary stats please let me know.
I am working on a shiny aplication to explore sums of squares in linear regression (link). This application has three sliderInput, so the user can choose: (i) the regression slope; (ii) the sample size and (iii) the standard deviation. With this inputs, the app generate a raw dataset to plot some graphs. This is working fine with the reactive function. Any change in one parameter will generate new data. My problem is that I want to include a buttom to "refresh" all values, actually to re-run the functions that generate these parameters.
So my question is how do I include this in the server?
I know I have to include the buttom in the ui:
actionButton(inputId = "refresh", label = "Refresh" ,
icon = icon("fa fa-refresh"))
)
But I dont know how to use this buttom to rerun the reactive functions that generate the data. This is the code that generates the data in the server:
### Saving data:
Rawdata <- reactive({
slope <- input$slope
SD <- input$SD
sample <- input$sample
x <- round(1:sample + rnorm(n = sample, mean = 1, sd = 1), digits = 2)
y <- round(slope * (x) + rnorm(n = sample, mean = 3, sd = SD ), digits = 2)
mod <- lm(y ~ x, data.frame(y,x))
ypred <- predict(mod)
Rawdata <- data.frame(y, x, ypred)
})
The full source code is available in github:
ui
| server
I appreciate any suggestion.
Best wishes,
Gustavo
You can isolate other input variables and make actionButton only dependency for reactive expression:
library(shiny)
shinyApp(
server = function(input, output, session) {
rawdata <- reactive({
# Make action button dependency
input$refresh
# but isolate input$sample
isolate(rnorm(input$sample))
})
output$mean <- renderText({ mean(rawdata()) })
},
ui = fluidPage(
actionButton(inputId = "refresh",
label = "Refresh", icon = icon("fa fa-refresh")),
sliderInput(inputId = "sample",
label = "Sample size",
value = 50, min = 10, max = 100),
textOutput("mean")
)
)