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)})
}
Related
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)
Im building a shinyapp from a log regression using the DynNom::DNbuilder R package. I obtained the ui.R, server.R and global.R code and the app works. However, I'm trying to change the format of the sliders and the labels but I haven't been able to do so.
I'd appreciate if someone could shed some light here . Thanks!
Here's my model and the labels i would like the app to show:
data <- data.frame(
x = c(0,1,0),
y = c(3,6,2),
z = c(1.3, 2.8, 3.1),
w = c(1,0,0)
)
model <- lrm(x ~ y + z + w, data = data)
modellabels <- c("ylabel", "zlabel", "wlabel")
Here's the DNbuilder code:
model <- lrm(x ~ y + z + w, data =data
DNbuilder(model, data = data, clevel = 0.95, m.summary = c("raw"), covariate = c("numeric"))
Here's what I got after running DNbuilder:
**ui.R**
ui = bootstrapPage(fluidPage(
titlePanel('app'),
sidebarLayout(sidebarPanel(uiOutput('manySliders'),
uiOutput('setlimits'),
actionButton('add', 'Predict'),
br(), br(),
helpText('Press Quit to exit the application'),
actionButton('quit', 'Quit')
),
mainPanel(tabsetPanel(id = 'tabs',
tabPanel('Graphical Summary', plotlyOutput('plot')),
tabPanel('Numerical Summary', verbatimTextOutput('data.pred')),
tabPanel('Model Summary', verbatimTextOutput('summary'))
)
)
)))
----------
**server.R**
server = function(input, output){
observe({if (input$quit == 1)
stopApp()})
limits <- reactive({ if (input$limits) { limits <- c(input$lxlim, input$uxlim) } else {
limits <- limits0 } })
output$manySliders <- renderUI({
slide.bars <- list()
for (j in 1:length(preds)){
if (terms[j+1] == "factor"){
slide.bars[[j]] <- list(selectInput(paste("pred", j, sep = ""), names(preds)[j], preds[[j]]$v.levels, multiple = FALSE))
}
if (terms[j+1] == "numeric"){
if (covariate == "slider") {
slide.bars[[j]] <- list(sliderInput(paste("pred", j, sep = ""), names(preds)[j],
min = preds[[j]]$v.min, max = preds[[j]]$v.max, value = preds[[j]]$v.mean))
}
if (covariate == "numeric") {
slide.bars[[j]] <- list(numericInput(paste("pred", j, sep = ""), names(preds)[j], value = zapsmall(preds[[j]]$v.mean, digits = 4)))
}}}
do.call(tagList, slide.bars)
})
output$setlimits <- renderUI({
if (is.null(DNlimits)){
setlim <- list(checkboxInput("limits", "Set x-axis ranges"),
conditionalPanel(condition = "input.limits == true",
numericInput("uxlim", "x-axis upper", zapsmall(limits0[2], digits = 2)),
numericInput("lxlim", "x-axis lower", zapsmall(limits0[1], digits = 2))))
} else{ setlim <- NULL }
setlim
})
a <- 0
new.d <- reactive({
input$add
input.v <- vector("list", length(preds))
for (i in 1:length(preds)) {
input.v[[i]] <- isolate({
input[[paste("pred", i, sep = "")]]
})
names(input.v)[i] <- names(preds)[i]
}
out <- data.frame(lapply(input.v, cbind))
if (a == 0) {
input.data <<- rbind(input.data, out)
}
if (a > 0) {
if (!isTRUE(compare(old.d, out))) {
input.data <<- rbind(input.data, out)
}}
a <<- a + 1
out
})
p1 <- NULL
old.d <- NULL
data2 <- reactive({
if (input$add == 0)
return(NULL)
if (input$add > 0) {
if (!isTRUE(compare(old.d, new.d()))) {
isolate({
mpred <- getpred.DN(model, new.d(), set.rms=T)$pred
se.pred <- getpred.DN(model, new.d(), set.rms=T)$SEpred
if (is.na(se.pred)) {
lwb <- "No standard errors"
upb <- "by 'lrm'"
pred <- mlinkF(mpred)
d.p <- data.frame(Prediction = zapsmall(pred, digits = 3),
Lower.bound = lwb, Upper.bound = upb)
} else {
lwb <- sort(mlinkF(mpred + cbind(1, -1) * (qnorm(1 - (1 - clevel)/2) * se.pred)))[1]
upb <- sort(mlinkF(mpred + cbind(1, -1) * (qnorm(1 - (1 - clevel)/2) * se.pred)))[2]
pred <- mlinkF(mpred)
d.p <- data.frame(Prediction = zapsmall(pred, digits = 3),
Lower.bound = zapsmall(lwb, digits = 3),
Upper.bound = zapsmall(upb, digits = 3))
}
old.d <<- new.d()
data.p <- cbind(d.p, counter = 1, count=0)
p1 <<- rbind(p1, data.p)
p1$counter <- seq(1, dim(p1)[1])
p1$count <- 0:(dim(p1)[1]-1) %% 11 + 1
p1
})
} else {
p1$count <- seq(1, dim(p1)[1])
}}
rownames(p1) <- c()
p1
})
output$plot <- renderPlotly({
if (input$add == 0)
return(NULL)
if (is.null(new.d()))
return(NULL)
coll=c("#0E0000", "#0066CC", "#E41A1C", "#54A552", "#FF8000", "#BA55D3",
"#006400", "#994C00", "#F781BF", "#00BFFF", "#A9A9A9")
lim <- limits()
yli <- c(0 - 0.5, 10 + 0.5)
dat2 <- data2()
if (dim(data2())[1] > 11){
input.data = input.data[-c(1:(dim(input.data)[1]-11)),]
dat2 <- data2()[-c(1:(dim(data2())[1]-11)),]
yli <- c(dim(data2())[1] - 11.5, dim(data2())[1] - 0.5)
}
in.d <- input.data
xx <- matrix(paste(names(in.d), ": ", t(in.d), sep = ""), ncol = dim(in.d)[1])
Covariates <- apply(xx, 2, paste, collapse = "<br />")
p <- ggplot(data = dat2, aes(x = Prediction, y = counter - 1, text = Covariates,
label = Prediction, label2 = Lower.bound, label3=Upper.bound)) +
geom_point(size = 2, colour = coll[dat2$count], shape = 15) +
ylim(yli[1], yli[2]) + coord_cartesian(xlim = lim) +
labs(title = "95% Confidence Interval for Response",
x = "Probability", y = "") + theme_bw() +
theme(axis.text.y = element_blank(), text = element_text(face = "bold", size = 10))
if (is.numeric(dat2$Upper.bound)){
p <- p + geom_errorbarh(xmax = dat2$Upper.bound, xmin = dat2$Lower.bound,
size = 1.45, height = 0.4, colour = coll[dat2$count])
} else{
message("Confidence interval is not available as there is no standard errors available by 'lrm' ")
}
gp <- ggplotly(p, tooltip = c("text", "label", "label2", "label3"))
gp$elementId <- NULL
gp
})
output$data.pred <- renderPrint({
if (input$add > 0) {
if (nrow(data2()) > 0) {
if (dim(input.data)[2] == 1) {
in.d <- data.frame(input.data)
names(in.d) <- names(terms)[2]
data.p <- cbind(in.d, data2()[1:3])
}
if (dim(input.data)[2] > 1) {
data.p <- cbind(input.data, data2()[1:3])
}}
stargazer(data.p, summary = FALSE, type = "text")
}
})
output$summary <- renderPrint({
print(model)
})
}
----------
**global.R**
library(ggplot2)
library(shiny)
library(plotly)
library(stargazer)
library(compare)
library(prediction)
library(rms)
load('data.RData')
source('functions.R')
t.dist <- datadist(data)
options(datadist = 't.dist')
m.summary <- 'raw'
covariate <- 'numeric'
clevel <- 0.95
I am not quite sure which type of shiny widget (or labels) you mean, but I have some comments.
Firstly, you need to make sure defining your variables' class correctly (e.g. as factors, numeric, ...), for example, by adding the following code before fitting your model:
> data$y <- as.factor(data$y)
This is especially important for factors so it gets factor levels. For numerical variables, you can get a shiny slider (by default) or a numeric input (using covariate = c("numeric")).
The labels for widgets are the same as the variable names. So the easiest way to adjust them is by changing the variable names as you like before fitting your model:
> names(data)
[1] "x" "y" "z"
> names(data)[2] <- 'ylabel'
> names(data)
[1] "x" "ylabel" "z"
> model <- lrm(x ~ ylabel + z, data = data)
Alternatively, the labels can be changed by adjusting the 'preds' object in the 'data.RData'. For example, you can use the following code to change labels:
> names(preds)
[1] "y" "z"
> names(preds)[1] <- 'labelled y'
> names(preds)
[1] "labelled y" "z"
> save.image(file = "data.RData")
Basically, I want to make this R plot interactive. http://rblogbyjordan.com/posts/solving-a-differential-equation-numerically-with-r/
I'm running into issues with the results data frame
output:html_document
runtime:shiny
library(shiny)
library(ggplot2)
Define UI for application
ui <- fluidPage(# Application title
titlePanel("Pendulum."),
# Sidebar with a slider input for mass
sidebarLayout(
sidebarPanel(
sliderInput(
"mass",
"Mass:",
min = 1,
max = 50,
value = 25
),
sliderInput(
"length",
"Length:",
min = 1,
max = 50,
value = 3
),
sliderInput(
"theta0",
"Starting Theta:",
min = 1,
max = 180,
value = 60
),
sliderInput(
"theta_dot0",
"Starting Theta dot:",
min = 0,
max = 10,
value = 0
),
sliderInput(
"time",
"how long do you want to observe the pendulum:",
min = 1,
max = 30,
value = 15
)
),
# Show a plot of the generated distribution
mainPanel(plotOutput("linePlot"))
))
Define server logic
server <- function(input, output) {
#constants
g <- 9.82 #Gravitational constant
mu <- .1 # Mu represents the loss of energy due to air resistance+
# reactive function that finds theta dub dot
theta_dubdot <- reactive(function(theta, theta_dot) {
return(-mu * theta_dot - (input$mass * g / input$length) * sin(theta))
})
# reactive function that finds theta
find_theta <- reactive(function(t.end) {
theta <- input$theta0
theta_dot <- input$theta_dot0
delta.t <- .001
for (t in seq(from = 0, to = t.end, by = delta.t)) {
theta <- theta + theta_dot * delta.t
theta_dot <- theta_dot + theta_dubdot()(theta, theta_dot) * delta.t
}
return(theta)
})
# creating a data frame to hold the results
rv <- reactiveValues(
result = data.frame("t" = seq(0, input$time , .1),
"theta" = seq(0, input$time , .1)))
# fill the data frame with the results every time input$time is changed
observeEvent(input$time,{
index <- 0
for (i in seq(0, input$time, .1)) {
index <- index + 1
rv$result()[index, ]$theta <- find_theta()(i)
}
})
output$linePlot <- renderPlot
({
# draw the plot with the specified parameters
ggplot(rv$result(), aes_string(t, theta * input$length)) +
geom_line() +
theme_dark() +
xlab("time") +
ylab("Theta * Length") # creating the plot
})
}
Run the application
shinyApp(ui = ui, server = server)
the expected results would be an interactive plot that changes based on starting parameters
the actual result is an error:
Warning: 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.)
59: stop
58: .getReactiveEnvironment()$currentContext
57: .subset2(x, "impl")$get
56: $.reactivevalues
50: server [#27]
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.)
Jordan,
I debugged your code as shown below. Refer to the comment in server.R for the modifications I made. Basically, reactiveValues() can only take static values as they are reactive source objects. Thus, your rv$result has to be defined with reactive(). For more details, refer to this documentation: https://shiny.rstudio.com/articles/reactivity-overview.html. Hope this helps.
# Load required packages --------------------------------------------------
library(shiny)
library(ggplot2)
# Build ui.R --------------------------------------------------------------
defaultTime <- 1 ## Changed it to 1 for rapid debugging
ui <- fluidPage(# Application title
titlePanel("Pendulum."),
# Sidebar with a slider input for mass
sidebarLayout(
sidebarPanel(
sliderInput(
"mass",
"Mass:",
min = 1,
max = 50,
value = 25
),
sliderInput(
"length",
"Length:",
min = 1,
max = 50,
value = 3
),
sliderInput(
"theta0",
"Starting Theta:",
min = 1,
max = 180,
value = 60
),
sliderInput(
"theta_dot0",
"Starting Theta dot:",
min = 0,
max = 10,
value = 0
),
sliderInput(
"time",
"how long do you want to observe the pendulum:",
min = 1,
max = 30,
value = defaultTime
)
),
# Show a plot of the generated distribution
mainPanel(plotOutput("linePlot"))
))
# Build server.R ----------------------------------------------------------
server <- function(input, output) {
#constants
g <- 9.82 #Gravitational constant
mu <- .1 # Mu represents the loss of energy due to air resistance+
# reactive function that finds theta dub dot
theta_dubdot <- reactive(function(theta, theta_dot) {
return(-mu * theta_dot - (input$mass * g / input$length) * sin(theta))
})
# reactive function that finds theta
find_theta <- reactive(function(t.end) {
theta <- input$theta0
theta_dot <- input$theta_dot0
delta.t <- .001
for (t in seq(from = 0, to = t.end, by = delta.t)) {
theta <- theta + theta_dot * delta.t
theta_dot <- theta_dot + theta_dubdot()(theta, theta_dot) * delta.t
}
return(theta)
})
# creating a data frame to hold the results
# rv <- reactiveValues(
# result = data.frame("t" = seq(0, input$time , .1),
# "theta" = seq(0, input$time , .1)))
# fill the data frame with the results every time input$time is changed
# observeEvent(input$time,{
# index <- 0
# for (i in seq(0, input$time, .1)) {
# index <- index + 1
# rvResult()[index, ]$theta <- find_theta()(i)
# }
#
# })
### rv$result uses input$time so it needs to be reactive() not reactiveValues()
rvResult <- reactive({
req(input$time)
outputDF <- data.frame("t" = seq(0, input$time , .1),
"theta" = seq(0, input$time , .1))
index <- 0
for (i in seq(0, input$time, .1)) {
index <- index + 1
computedTheta <- find_theta()(i)
print(computedTheta)
outputDF$theta[index] <- computedTheta
}
return(outputDF)
})
output$linePlot <- renderPlot({
print(rvResult())
# draw the plot with the specified parameters
ggplot(rvResult(), aes(t, theta * input$length)) +
geom_line() +
theme_dark() +
xlab("time") +
ylab("Theta * Length") # creating the plot
})
}
# Launch the Shiny app ----------------------------------------------------
shinyApp(ui = ui, server = server, options = list(launch.browser = TRUE))
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() })
}
}
)
I am trying to create an interactive data set and I need to subset it for calculations. When I try to extract certain rows and columns I get this error message about xtable being applied object of class "C('double','numeric')". Here is my code.
ui.r
library(shiny)
require(ggplot2)
shinyUI(fluidPage(
titlePanel("Vasicek Model Example"),
sidebarLayout(
sidebarPanel(
numericInput("sim", "Simulations", value = 100),
numericInput("loans", "Loans", value = 10),
numericInput("M", "Systemic Risk Factor", value = 0),
numericInput("rho", "Firm Correlation", value = 0),
sliderInput("bins", "Number of Bins:", min = 1, max = 50, value = 30),
submitButton("Submit")
),
mainPanel(
tabsetPanel(
tabPanel("Debug", tableOutput("probs"), tableOutput("dftable")),
tabPanel(plotOutput("distPlot"), tableOutput("sumtable"),
tableOutput("tabs"))
)
)
)))
server.r
library(shiny)
require(ggplot2)
shinyServer(function(input,output){
TMo <- reactive({
matrix(c(.90, .05, .04, .01,
.05, .80, .10, .05,
.05, .25, .60, .10,
.00, .00, .00, 1.0), nrow=4, ncol=4, byrow=T)
})
Pprob <- reactive({
TMo()[1:3, 4]
})
output$probs <- renderTable({
Pprob()
})
plotdata <- reactive({
R <- vector()
c <- vector()
DefRate <- vector()
groups <- vector()
ctr <- 0
for(group in 1:3){
c[group] <- qnorm(Pprob()[group])
for(i in 1:input$sim){
e <- matrix(data = rnorm(n = input$loans, mean = 0, sd = 1))
ctr <- ctr + 1
default <- 0
for(j in 1:input$loans){
R[j] <- sqrt(input$rho) * M + sqrt(1 - input$rho) * e[j]
if(R[j] <= c[group]){
default + 1
}
if(j == input$loans){
DefRate[ctr] <- default/input$loans
if(group == 1){
groups[ctr] = 'A'
}
else if(group == 2){
groups[ctr] = 'B'
}
else{
groups[ctr] = 'C'
}
}
if(group == 3 & i == input$sims & j == input$loans){
DefData <- cbind(DefRate,groups)
as.data.frame(DefData)
}
}
}
}
})
output$dftable <- renderTable({
head(plotdata())
})
#output$distPlot <- renderPlot({
#bins <- seq(min(x), max(x), length.out = input$bins + 1)
#DR_plots <- ggplot(DData, aes(x=DData$Default_Rate, fill=DData$Credit_Rating))
#DR_Hist_options <- geom_histogram(binwidth = .01, alpha=.5, position = "identity")
#DR_Hist <- DR_plots + DR_Hist_options
#DR_Hist
#hist(x, breaks = bins, col = 'darkgray', border = 'white',
#main = "Default Rate Distribution", xlab = "Default Rates",
#ylab = "Frequency")
#})
#output$tabs <- renderTable({
#x <- DR_Data
#head(x)
#})
})
excuse the commented out sections. I'm was debugging to try to figure out the source of the problem. Thank you for the help.