How to make it into User Interface in Shiny in R? - r

I have a program at below here, but I wish to make it into a Graphic User Interface in shiny in R. But I am really new to shiny. Here is the code :
#Optimization to find w for a sigmoid with given
#multiple samples for one input and one output
#x1, x2... are different observation for one x input
require(ggplot2)
generate_data<- function(n){
x_neg<- -3L
x_pos<- 3L
scale<- 1.5
n_samples<- n
x_train<- matrix(c(rnorm(n_samples) + x_pos
, rnorm(n_samples) + x_neg)*scale, byrow = T)
y_train<- matrix(c(rep(1, n_samples), rep(0, n_samples)), byrow = T)
list(x_train, y_train)
}
n <- 10
data_train<- generate_data(n)
x_train<- as.matrix(data_train[[1]])
y_train<- as.matrix(data_train[[2]])
plot(x_train, y_train, col='green', pch= 3
, ylim= c((min(y_train)-0.2), (max(y_train)+0.2)))
#create tensor:
unity_matrix<- matrix(rep(1, nrow(x_train)))
x_tensor<- cbind(unity_matrix, x_train)
sigmoid_neuron<- function(x, w) {
output<- 1/(1 + exp(-(x_tensor%*%w)))
}
w<- matrix(rnorm(2), byrow = T)#initialize
(sigmoid_output<- sigmoid_neuron(x= x_tensor, w= w))
points(x_train, sigmoid_neuron(x_tensor, w), col='blue', pch= 19)
Grad<- matrix(rep(0, 2), byrow = T)
compute_gradients<- function(x, y, h) {
Grad[1]<- mean(h- y)
Grad[2]<- mean((h-y)*x)
error<<- (h-y)
return(Grad)
}
compute_gradients(x= x_train, y= y_train, h= sigmoid_output)
##manually cycle through the code chunk to check if the algo works
learningRate<- 0.2
w<- matrix(rnorm(2), byrow = T)#initialize
(sigmoid_output<- sigmoid_neuron(x= x_tensor, w= w))
(grad<- compute_gradients(x_train, y_train, sigmoid_output))
w<- w - learningRate*grad
y_train
##tune sigmoid
learningRate<- 0.2
Grad<- matrix(rep(0, 2), byrow = T)
w<- matrix(rnorm(2), byrow = T)#initialize
idx_end<- 1000
error_history<- list()
for (i in 1:idx_end) {
sigmoid_output<- sigmoid_neuron(x= x_tensor, w= w)
grad<- compute_gradients(x_train, y_train, sigmoid_output)
error_history[[i]]<- error
w<- w - learningRate*grad
}
grad; sigmoid_output; y_train; w
points(x_train, sigmoid_neuron(x_tensor, w), col='red', pch= 4)
error_history_rmse<- sapply(1:length(error_history), function(x) sqrt(mean(error_history[[x]]^2)))
qplot(seq_along(error_history_rmse), error_history_rmse
, ylim = c(0, 0.1)
)
#dev.off()
My problem is, how can I create a Sigmoid Curve (at mainPanel) which I use the sliderInput to adjust the value of idx_end (at the line of 56) on the x-axis?
Here is my code, what should I modify or add to my Server?
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("x_range", "idx_end",
min = 0, max = 10000, value = c(0, 1000), step = 100)
),
mainPanel(
plotOutput("distPlot"))))
server <- function(input, output, session) {
output$distPlot <- renderPlot({
plot(seq_along(error_history_rmse), error_history_rmse,
xlim = c(0, input$x_range[2]),
#ylim = c(0,0.1),
col = 'darkgray',
border = 'white')})}
shinyApp(ui, server)
Can anyone help me? Really will appreciate it..

You can pretty much just slot in your code into the renderPlot function. Then assign input$x_range[2] to idx_end. However, there's no need to include all of your code in renderPlot, just the code that reacts to user input and makes the plot. Hence, I've placed most of your code in a source R file called 'plot_data.R' then used source to populate the global environment with variables that are static.
library(shiny)
source("plot_data.R")
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("x_range", "idx_end",
min = 0, max = 10000, value = c(0, 1000), step = 100)
),
mainPanel(
plotOutput("distPlot"))))
server <- function(input, output, session) {
output$distPlot <- renderPlot({
learningRate<- 0.2
Grad<- matrix(rep(0, 2), byrow = T)
w<- matrix(rnorm(2), byrow = T)#initialize
idx_end <- input$x_range[2]
error_history<- list()
for (i in 1:idx_end) {
sigmoid_output<- sigmoid_neuron(x= x_tensor, w= w)
grad<- compute_gradients(x_train, y_train, sigmoid_output)
error_history[[i]]<- error
w<- w - learningRate*grad
}
error_history_rmse<- sapply(1:length(error_history), function(x) sqrt(mean(error_history[[x]]^2)))
plot(seq_along(error_history_rmse), error_history_rmse,
xlim = c(0, input$x_range[2]),
#ylim = c(0,0.1),
col = 'darkgray',
border = 'white')})}
shinyApp(ui, server)

Related

Error in my ShinyApp on R: Non numeric matrix extent

Every time I try to run the shiny app on R I get this error. How to fix it?
I found out that the error is regarding samples <- matrix(sample(1:n),ncol=K)
But I don't understand why.
This is the code of my server:
server <- function(input, output) {
output$distPlot <- renderPlot({
r=input$r
n=input$n
K=input$k
sim=input$sim
p=input$p
noi=input$noi
lsEigen0 <- replicate(1, matrix(rep(0, sim*p),
nrow=sim, ncol = p), simplify=FALSE)
lsmethod0 <- replicate(1, matrix(rep(0, sim*p),
nrow=sim, ncol = p), simplify=FALSE)
choose0 <- replicate(1, rep(0, p), simplify=FALSE)
for (i in 1:sim) {
samples <- matrix(sample(1:n), ncol=K)
#df <- rmvnorm(n = n, mean = rep(0, p), sigma = diag(p))
#data0 <- dataset(df,r,noi)
#for (da in 1:1) {
# lsEigen0[[da]][i,] <- svd(data0[[da]])$d
#lsmethod0[[da]][i,] <- method(data0[[da]], samples)
#min_err0 <- which.min(lsmethod0[[da]][i,])
#choose0[[da]][min_err0] <- choose0[[da]][min_err0] +1
#}
}
#par(mfrow=c(1,2))
#plot1 = plot(1:p, colMeans(lsEigen0[[1]]),
xlab="kth Eigenvalue", ylab="Value",
main="Scree plot data set ", type = "b", pch = 19,
lty = 1, col = 1)
#plot2 = plot(1:p, colMeans(lsmethod0[[1]]), xlab="Rank r",
ylab="Value", main= "Error data set ",
type = "b", pch = 19, lty = 1, col = 1)
})
}
# Run the application
shinyApp(ui = ui, server = server)
The code runs but in the shiny app I get the error
I have tried to fix it by myself but I don't get it.

SIR model in Rstudio shiny

I´m trying to build the basic SIR model in Rstudio shiny. The model takes 2 parameters (beta = infection rate/day, gamma = recovery date/day), 3 initial values (S = numbers of susceptibles, I = infectious, R = recovered) and last variable is time (in days).
Here is the code of it just in R markdown:
library(deSolve)
sir_equations <- function(time, variables, parameters) {
with(as.list(c(variables, parameters)), {
dS <- -beta * I * S
dI <- beta * I * S - gamma * I
dR <- gamma * I
return(list(c(dS, dI, dR)))
})
}
parameters_values <- c(
beta = 0.05, # infectious rate/day
gamma = 0.5 # recovery rate/day
)
initial_values <- c(
S = 1000, # susceptibles
I = 1, # infectious
R = 0 # recovered (immune)
)
time_values <- seq(0, 10) #number of days (0-10)
sir_values_1 <- ode(
y = initial_values,
times = time_values,
func = sir_equations,
parms = parameters_values
)
sir_values_1 <- as.data.frame(sir_values_1) # convert to data frame
with(sir_values_1, {
plot(time, S, type = "l", col = "blue",
xlab = "period (days)", ylab = "number of people")
lines(time, I, col = "red")
lines(time, R, col = "green")
})
legend("right", c("susceptibles", "infectious", "recovered"),
col = c("blue", "red", "green"), lty = 1, bty = "n")
Now I want to add this into R shiny, where the user can input the beta, gamma and days value (sliderbar, or just input), then it will plot the result. I´m pretty new to R and tried some variations here, like putting the user input into ,,UI,, the calculating into ,,server,, then combine it in like this shinyApp(ui = ui, server = server). This code below I tried, but its not working. Can you guys help me, what I´m doing wrong, and what to follow to be able to put the code into R shiny?
library(deSolve)
library(shiny)
ui <- fluidPage(
sliderInput(inputId = "time_values", label = "Dny", value = 10, min = 1, max = 100),
sliderInput(inputId = "beta", label ="Míra nákazy", value = 0.05, min = 0.00, max = 1, step = 0.01),
sliderInput(inputId = "gamma", label ="Míra uzdravení", value = 0.5, min = 0.00, max = 1, step = 0.1),
plotOutput("plot")
)
server <- function(input, output) {
sir_equations <- function(time, variables, parameters) {
with(as.list(c(variables, parameters)), {
dS <- -beta * I * S
dI <- beta * I * S - gamma * I
dR <- gamma * I
return(list(c(dS, dI, dR)))
})
}
initial_values <- c(S = 1000, I = 1, R = 0)
sir_values_1 <- ode(
y = initial_values,
times = time_values,
func = sir_equations,
parms = parameters_values
)
output$plot <- renderPlot({
plot(rnorm(input$time_values))
plot(rnorm(input$beta))
plot(rnorm(input$gamma))
})
}
shinyApp(ui = ui, server = server)
Thanks
Michal
I guess it is something like this you want?
library(deSolve)
library(shiny)
ui <- fluidPage(
sliderInput(inputId = "time_values", label = "Dny", value = 10, min = 1, max = 100),
sliderInput(inputId = "beta", label ="Míra nákazy", value = 0.05, min = 0, max = 1, step = 0.01),
sliderInput(inputId = "gamma", label ="Míra uzdravení", value = 0.5, min = 0, max = 1, step = 0.1),
plotOutput("plot")
)
server <- function(input, output) {
sir_equations <- function(time, variables, parameters) {
with(as.list(c(variables, parameters)), {
dS <- -beta * I * S
dI <- beta * I * S - gamma * I
dR <- gamma * I
return(list(c(dS, dI, dR)))
})
}
initial_values <- c(S = 1000, I = 1, R = 0)
sir_values_1 <- reactiveValues(val = data.frame())
observe({
sir_values_1$val <- as.data.frame(ode(
y = initial_values,
times = seq(0, input$time_values),
func = sir_equations,
parms = c(beta=input$beta, gamma=input$gamma)
))
})
output$plot <- renderPlot({
with(sir_values_1$val, {
plot(sir_values_1$val$time, sir_values_1$val$S, type = "l", col = "blue",
xlab = "period (days)", ylab = "number of people")
lines(sir_values_1$val$time, sir_values_1$val$I, col = "red")
lines(sir_values_1$val$time, sir_values_1$val$R, col = "green")
legend("right", c("susceptibles", "infectious", "recovered"),
col = c("blue", "red", "green"), lty = 1, bty = "n")
})
})
}
shinyApp(ui = ui, server = server)
Here another solution without the need of an observer function. More about deSolve and shiny at: https://tpetzoldt.github.io/deSolve-shiny/deSolve-shiny.html
library("deSolve")
sir_equations <- function(time, variables, parameters) {
with(as.list(c(variables, parameters)), {
dS <- -beta * I * S
dI <- beta * I * S - gamma * I
dR <- gamma * I
return(list(c(dS, dI, dR)))
})
}
ui <- fluidPage(
sliderInput(inputId = "time_values", label = "Dny", value = 10, min = 1, max = 100),
sliderInput(inputId = "beta", label ="Míra nákazy", value = 0.05, min = 0.00, max = 1, step = 0.01),
sliderInput(inputId = "gamma", label ="Míra uzdravení", value = 0.5, min = 0.00, max = 1, step = 0.1),
plotOutput("plot")
)
server <- function(input, output) {
output$plot <- renderPlot({
initial_values <- c(S = 1000, I = 1, R = 0)
sir_values <- ode(
y = initial_values,
times = seq(0, input$time_values, length.out=1000),
func = sir_equations,
parms = c(beta=input$beta, gamma=input$gamma)
)
## easiest is to use the deSolve plot function
#plot(sir_values, mfrow=c(1,3))
## but you can also do it with own plot functions, e.g.:
matplot(sir_values[,1], sir_values[,-1], type="l", xlab="time", ylab="S, I, R")
legend("topright", col=1:3, lty=1:3, legend=c("S", "I", "R"))
})
}
shinyApp(ui = ui, server = server)
Just look at the error:
Warning: Error in ode: objet 'time_values' introuvable
In ode(), you should replace time_values by input$time_values and put the full ode() function in a reactive environment since you use some inputs:
sir_values_1 <- reactive({
ode(
y = initial_values,
times = input$time_values,
func = sir_equations,
parms = parameters_values
)
})
Then you have some errors in your plot but setting xlim and ylim should make it work. However, if you want to display multiple plots, you must define several plotOutput and renderPlot. Putting three plot in one renderPlot will not display the three of them but only the last one.

plotting 3D playes in R, anyone can look through the code

I hope anyone can help me :)
Write this code including shiny, but at the end it doesnt work the way I want it to.
If anyone can look through that code an tell me why the plot isnt working ?
You will see that there is an error at the end.
Ok first why istn the rgl window implemented into the GUI ?
Second how can I plot the 3D in bigger cube ?
If I dont open a 3D plot wihtout data it doesnt plot it at all :(
library(shiny)
library(rgl)
library(shinythemes)
library(devtools)
#install_github("rgl", "trestletech", "js-class")
#install_github("rgl", "trestletech", "js-class")
#######################################################################################
# User Interface #
#######################################################################################
ui <- fluidPage(theme = shinytheme("slate"),
#shinythemes::themeSelector(), # <--- Add this somewhere in the UI
headerPanel("Block Theory 0.1"),
sidebarPanel(
numericInput(inputId = "dd", label = "Dip direction:", value = "", width = "80%", min = 0, max = 360),
numericInput(inputId = "fa", label = "Fracture angle:", value = "", width = "80%", min = 0, max = 90),
numericInput(inputId = "position_x", label = "Position:", value = "", width = "40%"),
numericInput(inputId = "position_y", label = "", value = "", width = "40%"),
selectInput("form", "Form:",
c("Circle", "Square", "Ellipsoid")),
actionButton(inputId = "add", label = "Add a plane"),
actionButton(inputId = "plotbutton", label = "Update")
),
mainPanel(
plotOutput(outputId = "plot")
),
verbatimTextOutput(outputId = "log_planes")
)
#######################################################################################
# SERVER #
#######################################################################################
server <- function(input, output) {
data_planes <- data.frame()
makeReactiveBinding("data_planes")
observe({
input$add
isolate({
data_planes <<- rbind(data_planes, data.frame(input$dd, input$fa , input$position_x , input$position_y))
data_planes <<- na.omit(data_planes)
})
})
output$plot <- renderRglwidget({
# try(rgl.close())
input$plotbutton
isolate({
#######################################################################################
# Open 3d plot:
x<-sample(1:100, 100)
y<-sample(1:100, 100)
z<-sample(1:100, 100)
plot3d(x, y, z, type = "n",xlim = c(-10, 10), ylim = c(-10, 10), zlim = c(-30, 30))
#######################################################################################
while (i <= nrow(data_planes)) {
phi <- data_planes[i,1] * pi / 180
deta <- data_planes[i,2] * pi / 180
Px <- data_planes[i,3]
Py <- data_planes[i,4]
Pz <- 0
n <- c(-sin(deta)*sin(phi), sin(deta) * cos(phi), -cos(deta))
T <- matrix(c(cos(deta)*cos(phi), sin(deta), cos(deta)*sin(phi), -sin(deta)*cos(phi), cos(deta), -sin(deta)*sin(phi), -sin(phi), 0 , cos(phi)), nrow=3,ncol = 3, byrow = TRUE)
P_new <- T %*% c(Px,Py,Pz)
P_n <- -P_new %*% n # d = -P * n
# planes3d() plots equation: a*x + b*y + c*z + d = 0
a <- -sin(deta)*sin(phi)
b <- sin(deta) * cos(phi)
c <- -cos(deta)
d <- P_n
cols<-rgb(runif(5),runif(5),runif(5)) #random color genarator
planes3d(a, b, c , d , col = cols, alpha = 1.0)
i <- i + 1
}
})
})
output$log_planes <- renderPrint({na.omit(data_planes)})
}
#######################################################################################
shinyApp(ui = ui, server = server)
There are few mistakes in your app:
Firstly, in your ui instead of plotOutput(outputId = "plot") it should be rglwidgetOutput(outputId = "plot").
Secondly, you wont be able to plot in a loop and also you need to give rglwidget(). Just for demonstration purpose I have altered your server code by removing the loop. Have a look:
server <- function(input, output) {
data_planes <- data.frame()
makeReactiveBinding("data_planes")
observe({
input$add
isolate({
data_planes <<- rbind(data_planes, data.frame(input$dd, input$fa , input$position_x , input$position_y))
data_planes <<- na.omit(data_planes)
})
})
output$plot <- renderRglwidget({
# try(rgl.close())
input$plotbutton
# isolate({
#######################################################################################
# Open 3d plot:
x<-sample(1:100, 100)
y<-sample(1:100, 100)
z<-sample(1:100, 100)
plot3d(x, y, z, type = "n",xlim = c(-10, 10), ylim = c(-10, 10), zlim = c(-30, 30))
#######################################################################################
i=1;
# while (i <= nrow(data_planes)) {
phi <- data_planes[i,1] * pi / 180
deta <- data_planes[i,2] * pi / 180
Px <- data_planes[i,3]
Py <- data_planes[i,4]
Pz <- 0
n <- c(-sin(deta)*sin(phi), sin(deta) * cos(phi), -cos(deta))
T <- matrix(c(cos(deta)*cos(phi), sin(deta), cos(deta)*sin(phi), -sin(deta)*cos(phi), cos(deta), -sin(deta)*sin(phi), -sin(phi), 0 , cos(phi)), nrow=3,ncol = 3, byrow = TRUE)
P_new <- T %*% c(Px,Py,Pz)
P_n <- -P_new %*% n # d = -P * n
# planes3d() plots equation: a*x + b*y + c*z + d = 0
a <- -sin(deta)*sin(phi)
b <- sin(deta) * cos(phi)
c <- -cos(deta)
d <- P_n
cols<-rgb(runif(5),runif(5),runif(5)) #random color genarator
i <- i + 1
# }
planes3d(a, b, c , d , col = cols, alpha = 1.0)
rglwidget()
# })
})
output$log_planes <- renderPrint({na.omit(data_planes)})
}
The output you see from this code is:
EDIT:
To plot more than 1 plot at a time and adjust the x, y and z limits you can use this server code:
server <- function(input, output) {
data_planes <- data.frame()
makeReactiveBinding("data_planes")
observe({
input$add
isolate({
data_planes <<- rbind(data_planes, data.frame(input$dd, input$fa , input$position_x , input$position_y))
data_planes <<- na.omit(data_planes)
})
})
output$plot <- renderRglwidget({
# try(rgl.close())
input$plotbutton
# isolate({
#######################################################################################
# Open 3d plot:
x<-sample(1:100, 100)
y<-sample(1:100, 100)
z<-sample(1:100, 100)
plot3d(x, y, z, type = "n",xlim = c(min(x), max(x)), ylim = c(min(y), max(y)), zlim = c(min(z), max(z)))
####################################################
i=1;
while (i <= nrow(data_planes)) {
phi <- data_planes[i,1] * pi / 180
deta <- data_planes[i,2] * pi / 180
Px <- data_planes[i,3]
Py <- data_planes[i,4]
Pz <- 0
n <- c(-sin(deta)*sin(phi), sin(deta) * cos(phi), -cos(deta))
T <- matrix(c(cos(deta)*cos(phi), sin(deta), cos(deta)*sin(phi), -sin(deta)*cos(phi), cos(deta), -sin(deta)*sin(phi), -sin(phi), 0 , cos(phi)), nrow=3,ncol = 3, byrow = TRUE)
P_new <- T %*% c(Px,Py,Pz)
P_n <- -P_new %*% n # d = -P * n
# planes3d() plots equation: a*x + b*y + c*z + d = 0
a <- -sin(deta)*sin(phi)
b <- sin(deta) * cos(phi)
c <- -cos(deta)
d <- P_n
cols<-rgb(runif(5),runif(5),runif(5)) #random color genarator
i <- i + 1
planes3d(a, b, c , d , col = cols, alpha = 1.0)
}
rglwidget()
# })
})
output$log_planes <- renderPrint({na.omit(data_planes)})
}

How do I use animation in shiny in R to change data on plot without redrawing plot itself?

I am researching and comparing various versions of particle swarm optimization and differential evolution, and to aid me in visualizing convergence of each variant, I have developed a simple shiny app. My shiny app plots a contour map of the G2 function (code below), and then using simple animation it adds each generations' population as points on the contour plot, so I can see the evolution through generations. I notice a lag in the animation that to be in the shiny app redrawing the contour plot each time, instead of simply "removing" current data points and adding new data points to the plot as it loops through the generations. If I go below interval = 400 in animationOptions() of animate parameter, it does not render any faster, as that seems to be the fastest it can redraw the contour plot and data points. Is there a way to have the contour plot drawn only once, then data points added and removed as it loops through generations?
G2 = function(x) {
if (x[1] >= 0 & x[1] <= 10 & x[2] >= 0 & x[2] <= 10 &
x[1] * x[2] >= 0.75 & x[1] + x[2] <= 15) {
s <- cos(x[1]) ^ 4 + cos(x[2]) ^ 4
p <- 2 * cos(x[1]) ^ 2 * cos(x[2]) ^ 2
r <- sqrt(x[1] ^ 2 + 2 * x[2] ^ 2)
f <- -abs((s - p) / r)
} else {
f <- 0
}
return(f)
}
plotG2 <- function(main = "", sub = "") {
S <- matrix(0, 101, 101)
x1 <- (1:101 - 1) / 10
x2 <- x1
for (i in 1:101) {
for (j in 1:101) {
f <- -G2(c(x1[i], x2[j]))
#f <- -rosenbrock(1, 100, c(x1[i], x2[j]))
S[i, j] <- f
}
}
col = terrain.colors(100)
crange <- max(S) - min(S)
image(x1, x2, S, col = terrain.colors(100), axes = T,
xlab = "", ylab = "")
contour(x1, x2, S, col = col[100], lty = "solid", add = TRUE,
levels = c(0.05, 0.1, 0.2, 0.3, 0.4), vfont = c("sans serif",
"plain"), drawlabels = F)
title(main = main, sub = sub)
}
#Create list of random data points to cycle through
popList = list()
for (i in 1:5) {
popList[[i]] = matrix(runif(80, 0, 10), nrow = 2, ncol = 40)
}
library(shiny)
server <- function(input, output) {
output$distPlot <- renderPlot({
plotG2(paste("G2 iter ", input$obs, sep = ""), "Particle Swarm Optimization")
points(t(popList[[input$obs]]), col = "blue", pch = 19)
})
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("obs", "Number of observations:", min = 1,
max = 5, value = 1, step = 1,
animate = animationOptions(interval = 400, loop = TRUE))
),
mainPanel(plotOutput("distPlot"))
)
)
shinyApp(ui = ui, server = server)
No, you can't.
Very long answer: Plots are rendered as png (see ?plotPNG) before they're inserted in the web interface. So if you change something on the plot, you can't but rerender the entire image to be shown.

Calling additional functions in Shiny

I developed a simple shiny app that take as inputs a score my_x on a distribution with mean my_mean and standard deviation my_sd. As output, the app return a Lattice plot with a Normal Standard distribution with the corresponding z-score of my_x. Please find the code for the app on GitHub.
Now, I would like to add a second functionality to the app:
By checking a checkboxInput I would calculate, for example, the pnorm of the inputs and shade the relative area of the graph.
I wrote the code for the graph (here an example of the expected result), but I cannot figure out how to make it work in Shiny. In particular, I cannot figure how to make the function activated with the checkbox working properly with the first function drawing the graph.
library(lattice)
e4a <- seq(60, 170, length = 10000)
e4b <- dnorm(e4a, 110, 15)
#z-score is calculated with the inputs listed above:
z_score <- (my_x - my_mean)/my_sd
plot_e4d <- xyplot(e4b ~ e4a,
type = "l",
main = "Plot 4",
scales = list(x = list(at = seq(60, 170, 10)), rot = 45),
panel = function(x,y, ...){
panel.xyplot(x,y, ...)
panel.abline(v = c(z_score, 110), lty = 2)
xx <- c(60, x[x>=60 & x<=z_score], z_score)
yy <- c(0, y[x>=60 & x<=z_score], 0)
panel.polygon(xx,yy, ..., col='red')
})
print(plot_e4d)
I found a functioning solution. I am pretty sure that it is not the most efficient, but it works. It consists of an if/else statement within the server function calling the plot. I would like to thank #zx8754 for the inspiration.
Here is the ui.r file:
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("Standard Normal"),
sidebarPanel(
numericInput('mean', 'Your mean', 0),
numericInput('sd', 'Your standard deviation', 0),
numericInput('x', 'Your score', 0),
checkboxInput('p1', label = 'Probability of getting a score smaller than x or z', value = FALSE)
),
mainPanel(
h3('Standard Normal'),
plotOutput('sdNorm'),
h4('Your z-score is:'),
verbatimTextOutput('z'),
h4('Your lower tail probability is:'),
verbatimTextOutput('p1')
))
)
And the server.R file:
library(lattice)
shinyServer(
function(input, output){
output$sdNorm <- renderPlot({
dt1 <- seq(-3, 3, length = 1000)
dt2 <- dnorm(dt1, 0, 1)
my_mean <- input$mean
my_sd <- input$sd
my_x <- input$x
z <- (my_x - my_mean)/my_sd
if(input$p1){
xyplot(dt2 ~ dt1,
type = "l",
main = "Lower tail probability",
panel = function(x,y, ...){
panel.xyplot(x,y, ...)
panel.abline(v = c(z, 0), lty = 2)
xx <- c(-3, x[x>=-3 & x<=z], z)
yy <- c(0, y[x>=-3 & x<=z], 0)
panel.polygon(xx,yy, ..., col='red')
})
}else{
xyplot(dt2 ~ dt1,
type = "l",
main = "Standard Normal Distribution",
panel = function(x, ...){
panel.xyplot(x, ...)
panel.abline(v = c(z, 0), lty = 2)
})
}
})
output$z = renderPrint({
my_mean <- input$mean
my_sd <- input$sd
my_x <- input$x
z <- (my_x - my_mean)/my_sd
z
})
output$p1 <- renderPrint({
if(input$p1){
my_mean <- input$mean
my_sd <- input$sd
my_x <- input$x
p1 <- 1- pnorm(my_x, my_mean, my_sd)
p1
} else {
p1 <- NULL
}
})
}
)
This should work:
library(shiny)
library(lattice)
shinyApp(
ui = {
pageWithSidebar(
headerPanel("Standard Normal"),
sidebarPanel(
numericInput('mean', 'Your mean', 80),
numericInput('sd', 'Your standard deviation', 2),
numericInput('x', 'Your score', 250),
checkboxInput("zScoreArea", label = "Area under z-score", value = TRUE)
),
mainPanel(
h3('Standard Normal'),
plotOutput('sdNorm'),
h4('Your z-score is:'),
verbatimTextOutput('z_score')
))
},
server = {
function(input, output){
#data
dt1 <- seq(60, 170, length = 10000)
dt2 <- dnorm(dt1, 110, 15)
#xyplot panel= function()
myfunc <- reactive({
if(input$zScoreArea){
function(x,y, ...){
panel.xyplot(x,y, ...)
panel.abline( v = c(z_score(), 110), lty = 2)
xx <- c(60, x[x >= 60 & x <= z_score()], z_score())
yy <- c(0, y[x >= 60 & x <= z_score()], 0)
panel.polygon(xx,yy, ..., col='red')
}
}else{
function(x, ...){
panel.xyplot(x, ...)
panel.abline(v = c(z_score(), 110), lty = 2)}
}
})
#reactive z_score for plotting
z_score <- reactive({
my_mean <- input$mean
my_sd <- input$sd
my_x <- input$x
#return z score
(my_x - my_mean)/my_sd
})
output$sdNorm <- renderPlot({
xyplot(dt2 ~ dt1,
type = "l",
main = "Plot 4",
scales = list(x = list(at = seq(60, 170, 10)), rot = 45),
panel = myfunc()
)
})
output$z_score = renderPrint({ z_score() })
}
}
)

Resources