Shiny beginner question, but getting tired after reading the docs and apparently missing the point of isolate(). I am working on a simple app for simulating phenotype based on genotypes. Not important, unless you are a geneticist. What I want to achieve is that only changing values of m or N results in re-sampling genotypes G and displays them in the table. When I change mean effect or its std. dev., I want only the 1 st row values to change. Was trying to add isolate when I call currG() and currBetas() but no desired effect achieved. Would be grateful for some hints. The code:
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Phenotype simulator"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
sliderInput("N",
"Number of individuals:",
min=1000,
max=10000,
step = 1000,
value=5000),
sliderInput("m",
"Number of markers:",
min=1,
max=10,
step=1,
value=5),
sliderInput("betas_mu",
"Mean effect:",
min=0,
max=5,
step=.5,
value=1),
sliderInput("betas_sd",
"Effect SD:",
min=0,
max=3,
step=0.1,
value=1),
sliderInput("e_mu",
"Mean error:",
min=0,
max=0.5,
step=0.01,
value=0.25),
sliderInput("e_sd",
"Error SD:",
min=0,
max=1,
step=0.01,
value=1),
sliderInput("m_neg",
"Number of markers with negative effect:",
value = 0,
step = 1,
min = 0,
max = 5
),
sliderInput("q",
"Minor allele frequency:",
min=0,
max=1,
step=0.01,
value=.33),
# sliderInput("precision",
# "Decimals:",
# min=1,
# max=5,
# value=3),
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Show a plot of the generated distribution
mainPanel(
p("Error and simulated trait distributions", style="font-size:15pt"),
plotOutput("distPlot"),
p("Genotypes for the first 5 individuals", style="font-size:15pt"),
tableOutput("genos"),
p("Distribution of effect sizes", style="font-size:15pt"),
plotOutput("eff_distPlot")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
currG <- function() {
p <- 1 - input$q
q <- input$q
m <- input$m
N <- input$N
gt <- sample(x = c(0,1,2), size = (input$N * input$m), replace = T, prob = c(p^2, p*q, q^2))
G <- matrix(gt, ncol = m, byrow = T)
return(G)
}
currBetas <- function() {
cg <- currG()
m <- dim(cg)[2]
N <- dim(cg)[1]
m_neg <- input$m_neg
betas <- abs(rnorm(n = m, mean = input$betas_mu, sd = input$betas_sd))
negative_idx <- sample(c(1:m), size=m_neg, replace=F)
signs <- rep(1, times=m)
betas[negative_idx] <- -betas[negative_idx]
return(list(betas=betas, signs=signs))
}
currPheno <- function() {
G <- currG()
tmp <- currBetas()
N <- dim(G)[1]
m <- dim(G)[2]
m_neg <- input$m_neg
errors <- rnorm(n = N, mean = input$e_mu, sd = input$e_sd)
y <- G %*% (tmp$signs * tmp$betas) + errors
y2 <- round(y, digits = 3)
data <- data.frame(error = errors, y = y2)
dat <- data %>% pivot_longer(cols = c(error, y))
return(list(dat=dat, betas=betas, G=G))
}
output$eff_distPlot <- renderPlot({
dat <- data.frame(value=rnorm(n = 1000, mean = input$betas_mu, sd = input$betas_sd))
ggplot(dat, mapping = aes(x=value)) +
geom_histogram(mapping = aes(fill='orange')) +
theme_bw()
})
output$distPlot <- renderPlot({
new_data = currPheno()
ggplot(new_data$dat, mapping = aes(x=value)) +
geom_histogram(mapping = aes(fill=name), bins = input$bins) +
theme_bw() +
facet_wrap(~name)
})
output$genos <- renderTable({
G <- currG()
B <- currBetas()
G <- G[1:5,]
tmp <- apply(G, MARGIN = c(1,2), as.integer)
tmp <- cbind(c('effect', paste0("ind", 1:dim(G)[1])), rbind(round(B$betas, 3), G))
colnames(tmp) <- c(" ", paste0("SNP", c(1:dim(G)[2])))
print(tmp)
},
colnames = T
)}
# Run the application
shinyApp(ui = ui, server = server)
Indeed, reactiveValues along with observeEvent and observe seem to be a much nicer and cleaner way to achieve what I wanted. Still a lot to learn when it comes to Shiny but one step forward has been made. Thanx MrFlick for suggestions!
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Phenotype simulator"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
sliderInput("N",
"Number of individuals:",
min=1000,
max=10000,
step = 1000,
value=5000),
sliderInput("m",
"Number of markers:",
min=1,
max=10,
step=1,
value=5),
sliderInput("betas_mu",
"Mean effect:",
min=0,
max=5,
step=.5,
value=1),
sliderInput("betas_sd",
"Effect SD:",
min=0,
max=3,
step=0.1,
value=1),
sliderInput("e_mu",
"Mean error:",
min=0,
max=0.5,
step=0.01,
value=0.25),
sliderInput("e_sd",
"Error SD:",
min=0,
max=1,
step=0.01,
value=1),
sliderInput("m_neg",
"Number of markers with negative effect:",
value = 0,
step = 1,
min = 0,
max = 5
),
sliderInput("q",
"Minor allele frequency:",
min=0,
max=1,
step=0.01,
value=.33),
# sliderInput("precision",
# "Decimals:",
# min=1,
# max=5,
# value=3),
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Show a plot of the generated distribution
mainPanel(
p("Genotypes for the first 5 individuals", style="font-size:15pt"),
tableOutput("genos"),
tableOutput("betas"),
plotOutput("errors"),
plotOutput("phenos"),
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
rvals <- reactiveValues(
G = NULL,
betas = NULL,
errors = c(0),
phenos = c(0),
)
observeEvent(c(input$N, input$m, input$q), {
p <- 1 - input$q
q <- input$q
gt <- sample(x = c(0,1,2),
size = (input$N * input$m),
replace = T,
prob = c(p^2, p*q, q^2))
rvals$G <- matrix(gt, ncol = input$m, byrow = T)
})
observe({
betas <- abs(rnorm(n = input$m,
mean = input$betas_mu,
sd = input$betas_sd))
negative_idx <- sample(c(1:input$m), size=input$m_neg, replace=F)
signs <- rep(1, times=input$m)
betas[negative_idx] <- -betas[negative_idx]
rvals$betas <- betas
})
observe({
N <- dim(rvals$G)[1]
m <- dim(rvals$G)[2]
errors <- rnorm(n = N, mean = input$e_mu, sd = input$e_sd)
rvals$errors <- errors
})
observe({
phenos <- round(rvals$G %*% rvals$betas + rvals$errors, digits = 3)
rvals$phenos <- phenos
})
output$genos <- renderTable({
rvals$G[1:5,]
})
output$betas <- renderTable({
t(rvals$betas)
})
output$errors <- renderPlot({
x <- data.frame(errors = rvals$errors)
ggplot(x, mapping = aes(x = errors)) +
geom_histogram() +
theme_bw()
})
output$phenos <- renderPlot({
x <- data.frame(phenos = rvals$phenos)
ggplot(x, mapping = aes(x = phenos, fill = 'orange')) +
geom_histogram() +
theme_bw()
})
}
# Run the application
shinyApp(ui = ui, server = server)
Related
In running the below code, I'm not sure why it's not plotting. In other, more involved versions of this code it does plot; I've done line-by-line comparisons and can't see why it doesn't plot in this case. I've played with req(), if(isTruthy()...)) statements, with no luck. I tested the interpol() custom function in the console, and it works fine as shown in the image at the bottom of this post.
library(ggplot2)
library(shiny)
library(shinyMatrix)
interpol <- function(a, b) { # a = periods, b = matrix inputs
c <- rep(NA, a)
c[1] <- b[1]
c[a] <- b[2]
c <- approx(seq_along(c)[!is.na(c)], c[!is.na(c)], seq_along(c))$y # << interpolates
return(c)
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput('periods', 'Modeled periods (X variable):', min=1, max=10, value=10),
matrixInput("matrix1",
label = "Matrix 1:",
value = matrix(c(5), ncol = 1, dimnames = list("Base rate",NULL)),
cols = list(names = FALSE),
class = "numeric"),
matrixInput("matrix2",
label = "Matrix 2 (will link to Matrix 1):",
value = matrix(c(10,5), ncol = 2, dimnames = list(NULL,c("X","Y"))),
rows = list(extend = TRUE, delete = TRUE),
class = "numeric"),
),
mainPanel(
plotOutput("plot")
)
)
)
server <- function(input, output, session){
plotData <- reactive({
req(input$periods,input$matrix2) # << this doesn't help
tryCatch(
tibble(
X = seq_len(input$periods),
Y = interpol(input$periods,input$matrix2, drop = FALSE)
),
error = function(e) NULL
)
})
output$plot <- renderPlot({
req(plotData())
plotData() %>% ggplot() +
geom_line(aes(x = X, y = Y, colour = as.factor(Scenario))) +
theme(legend.title=element_blank())
})
}
shinyApp(ui, server)
library(dplyr) was missing function tibble was unknown
Your function interpol doesn't have a drop argument
Object 'Scenario' not found
library(ggplot2)
library(shiny)
library(shinyMatrix)
library(dplyr)
interpol <- function(a, b) { # a = periods, b = matrix inputs
c <- rep(NA, a)
c[1] <- b[1]
c[a] <- b[2]
c <- approx(seq_along(c)[!is.na(c)], c[!is.na(c)], seq_along(c))$y # << interpolates
return(c)
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput('periods', 'Modeled periods (X variable):', min=1, max=10, value=10),
matrixInput("matrix1",
label = "Matrix 1:",
value = matrix(c(5), ncol = 1, dimnames = list("Base rate",NULL)),
cols = list(names = FALSE),
class = "numeric"),
matrixInput("matrix2",
label = "Matrix 2 (will link to Matrix 1):",
value = matrix(c(10,5), ncol = 2, dimnames = list(NULL,c("X","Y"))),
rows = list(extend = TRUE, delete = TRUE),
class = "numeric"),
),
mainPanel(
plotOutput("plot")
)
)
)
server <- function(input, output, session){
plotData <- reactive({
# browser()
req(input$periods, input$matrix2) # << this doesn't help
tryCatch(
# drop = FALSE
tibble(
X = seq_len(input$periods),
Y = interpol(input$periods,input$matrix2)
),
error = function(e) NULL
)
})
output$plot <- renderPlot({
req(plotData())
# Error in is.factor: object 'Scenario' not found
# , colour = as.factor(Scenario)
plotData() %>% ggplot() +
geom_line(aes(x = X, y = Y)) +
theme(legend.title=element_blank())
})
}
shinyApp(ui, server)
So my function takes arguments from selectInput and sliderInput. After I click the button GO! it starts and generates the plot. After I use the slider to change the value it starts again, even without clicking on the button. How do I change it so it doesn't start without me clicking on the button? I don't want it to execute instantly while I'm still using the slider. I'm sorry if it's a stupid question, I'm a total beginner with shiny!
pageWithSidebar(
headerPanel('Algorytm genetyczny - optymalizacja funkcji Levy13'),
sidebarPanel(
selectInput('type_of', 'Typ algorytmu', choices = c("real-valued", "binary"), multiple = FALSE),
sliderInput('pop', 'Wielkosc populacji', min = 50, max = 1000, value = 100, step = 50, round = TRUE,
animate = TRUE, width = '400px'),
sliderInput('epoch', 'Liczba iteracji', min = 100, max = 2000, value = 1000, step = 100, round = TRUE,
animate = TRUE, width = '400px'),
actionButton("goButton", "Go!", class = "btn-success"),
),
mainPanel(
plotOutput('plot1'),
plotOutput('plot2'),
plotOutput('plot3')
)
)
library(GA)
library(tidyverse)
library(ranger)
library(caret)
library(tictoc)
function(input, output, session) {
levy13 <- function(x1, x2)
{
term1 <- (sin(3*pi*x1))^2
term2 <- (x1-1)^2 * (1+(sin(3*pi*x2))^2)
term3 <- (x2-1)^2 * (1+(sin(2*pi*x2))^2)
y <- term1 + term2 + term3
return(y)
}
x1 <- x2 <- seq(-10, 10, by = 0.1)
f <- outer(x1, x2, levy13)
output$plot1 <- renderPlot(persp3D(x1, x2, f, theta = 50, phi = 20, col.palette = bl2gr.colors) )
output$plot2 <- renderPlot(filled.contour(x1, x2, f, color.palette = bl2gr.colors))
observeEvent(input$goButton, {
output$plot3 <- renderPlot({
GA <- ga(type = input$type_of, fitness = function(x) - levy13(x[1], x[2]),
lower = c(-10, -10), upper = c(10, 10),
popSize = input$pop, maxiter = input$epoch, run = 300)
plot(GA)})
})
}
Sure, we can make it so our Go button controls when the chart is redrawn. And stop the chart from redrawing when the sliders change.
We can use isolate to stop the chart being automatically linked to the sliders.
The below minimal example shows this in action:
library(shiny)
ui <- fluidPage(
sliderInput("slider_1", "Slider 1", min = 1, max = 10, value = 5),
sliderInput("slider_2", "Slider 2", min = 1, max = 10, value = 5),
actionButton("myactionbutton", "Go"),
plotOutput("myplot")
)
server <- function(input, output, session) {
#Runs when action button is pressed
observeEvent(input$myactionbutton, {
#Prepare chart output
output$myplot <- renderPlot({
#Get the input of the sliders, but isolate them so changing the sliders won't cause our chart to redraw
numberofpoints <- isolate(input$slider_1) * isolate(input$slider_2)
#Prepare chart
hist(runif(numberofpoints))
})
})
}
shinyApp(ui, server)
Here is your code with isolate added, wrapped in a few extra lines to make it a fully working shiny app:
library(shiny)
library(GA)
library(tidyverse)
library(ranger)
library(caret)
library(tictoc)
ui <- fluidPage(
pageWithSidebar(
headerPanel('Algorytm genetyczny - optymalizacja funkcji Levy13'),
sidebarPanel(
selectInput('type_of', 'Typ algorytmu', choices = c("real-valued", "binary"), multiple = FALSE),
sliderInput('pop', 'Wielkosc populacji', min = 50, max = 1000, value = 100, step = 50, round = TRUE, animate = TRUE, width = '400px'),
sliderInput('epoch', 'Liczba iteracji', min = 100, max = 2000, value = 1000, step = 100, round = TRUE, animate = TRUE, width = '400px'),
actionButton("goButton", "Go!", class = "btn-success"),
),
mainPanel(
plotOutput('plot1'),
plotOutput('plot2'),
plotOutput('plot3')
)
)
)
server <- function(input, output, session) {
levy13 <- function(x1, x2)
{
term1 <- (sin(3*pi*x1))^2
term2 <- (x1-1)^2 * (1+(sin(3*pi*x2))^2)
term3 <- (x2-1)^2 * (1+(sin(2*pi*x2))^2)
y <- term1 + term2 + term3
return(y)
}
x1 <- x2 <- seq(-10, 10, by = 0.1)
f <- outer(x1, x2, levy13)
output$plot1 <- renderPlot(persp3D(x1, x2, f, theta = 50, phi = 20, col.palette = bl2gr.colors) )
output$plot2 <- renderPlot(filled.contour(x1, x2, f, color.palette = bl2gr.colors))
observeEvent(input$goButton, {
output$plot3 <- renderPlot({
GA <- ga(type = input$type_of, fitness = function(x) - levy13(x[1], x[2]),
lower = c(-10, -10), upper = c(10, 10),
popSize = isolate(input$pop), maxiter = isolate(input$epoch), run = 300)
plot(GA)})
})
}
shinyApp(ui, server)
I have a question about the checkboxInput in R shiny. When it is checked, the scatter plot should be colorful while when it is unchecked, the plot should be black. I have tried several methods, but it keeps colorful no matter whether it is checked or not. Could you please help me with fix the code? Thanks so much.
library(shiny)
library(dplyr)
library(ggplot2)
# Start a 'Shiny' part
shinyServer(function(input, output, session) {
# Create a new reactive variable
newVar <- reactive({
newData <- msleep %>% filter(vore == input$vore)
})
# Create a scatter plot
output$sleepPlot <- renderPlot({
newDat <- newVar()
g <- ggplot(newDat, aes(x = bodywt, y = sleep_total))
g + geom_point(size = input$size, aes(col = conservation))
})
# Create text info
output$info <- renderText({
newDat <- newVar()
paste("The average body weight for order", input$vore, "is", round(mean(newDat$bodywt, na.rm = TRUE), 2),
"and the average total sleep time is", round(mean(newDat$sleep_total, na.rm = TRUE), 2), sep = " ")
})
# Create output of observations
output$table <- renderTable({
newDat <- newVar()
newDat
})
})
library(ggplot2)
shinyUI(fluidPage(
# Application title
titlePanel("Investigation of Mammal Sleep Data"),
# Sidebar with options for the data set
sidebarLayout(
sidebarPanel(
h3("Select the mammal's biological order:"),
selectizeInput("vore", "Vore", selected = "omni",
choices = levels(as.factor(msleep$vore))),
br(),
sliderInput("size", "Size of Points on Graph",
min = 1, max = 10, value = 5, step = 1),
checkboxInput("conservation", h4("Color Code Conservation Status", style = "color:red;"))
),
# Show output
mainPanel(
plotOutput("sleepPlot"),
textOutput("info"),
tableOutput("table")
)
)
))
Try this
# Create a scatter plot
output$sleepPlot <- renderPlot({
newDat <- newVar()
colorme <- unique(newVar()$conservation)
ncolor <- length(colorme)
if (!input$conservation) {
mycolor <- c(rep("black",ncolor))
mylabels <- c(rep(" ",ncolor))
}
g <- ggplot(newDat, aes(x = bodywt, y = sleep_total)) +
geom_point(size = input$size, aes(col = conservation)) +
{if (!input$conservation) scale_color_manual(name=" ", values=mycolor, labels=mylabels)} +
{ if (!input$conservation) guides(color='none')}
g
})
You can adjust, as necessary.
I want to build forecast techniques that exponential smoothing method is one of my selection. However, I have some issues with representing the ggplot and the result/report of the calculation.
Initially, I am generating random dataset in order to be used for this technique where alpha and number of periods to be forecasted are determined by the user. For instance; i have 100 days and next 4 days are willing to be estimated with their lines -fit, upper and lower-. Then I want to learn the values of this data as a table.
When I try to visualize the plot, the error is: ggplot2 doesn't know how to deal with data of class mtstsmatrix
Secondly, I would like to monitor the data like:
require(shiny)
require(ggplot2)
require(forecast)
require(TTR)
shinyServer(function(input, output, session){
set.seed(123)
output$es1 <- renderPlot({
tmp <- data.frame(time = 1:100, sales = round(runif(100, 150, 879)) )
tmp.mean <- HoltWinters(x=tmp$sales, alpha = input$alpha, beta = FALSE,gamma=FALSE)
tmp.pred <- predict(tmp.mean,n.ahead = input$h, prediction.interval = TRUE)
y <- ggplot(tmp, aes(time, sales)) +
geom_line() +
geom_line(data=tmp.pred, aes(y=tmp.pred[,1]),color="red") +
geom_line(data=tmp.pred, aes(y=tmp.pred[,2]),color="blue") +
xlab("Days") +
ylab("Sales Quantity")+
ggtitle(title)
y })
output$infoes <- renderDataTable({
tmp <- data.frame(time = 1:100, sales = round(runif(100, 150, 879)) )
tmp.mean <- HoltWinters(x=tmp$sales, alpha = input$alpha, beta = FALSE,gamma=FALSE)
tmp.pred <- predict(tmp.mean,n.ahead = input$h, prediction.interval = TRUE)
tmp.pred
})
ui
require(shiny)
require(ggplot2)
require(forecast)
require(TTR)
shinyUI(pageWithSidebar(
headerPanel("Forecasting Methods"),
sidebarPanel(
h3(strong("Exponential Smoothing",style = "color:black")),
br(),
sliderInput("h","Number of periods for forecasting:",
min = 1, max = 20, step= 1, value = 4),
sliderInput("alpha","Alpha (Smoothing Parameter):",
min = 0.05, max = 1, step= 0.05, value = 0.01)
),
mainPanel(
tabsetPanel( id="tabs",
tabPanel("Exponential Smoothing",
value="panel",
plotOutput(outputId = "es1",
width = "900px",height = "400px"),
dataTableOutput(outputId="infoes"))
))))
You had a to make tmp.pred palatable for ggplot as was said in the comments. You also don't have to create the same data in multiple statements, a reactive command is good for that:
ui.R (unchanged)
require(shiny)
require(ggplot2)
require(forecast)
require(TTR)
shinyUI(pageWithSidebar(
headerPanel("Forecasting Methods"),
sidebarPanel(
h3(strong("Exponential Smoothing",style = "color:black")),
br(),
sliderInput("h","Number of periods for forecasting:",
min = 1, max = 20, step= 1, value = 4),
sliderInput("alpha","Alpha (Smoothing Parameter):",
min = 0.05, max = 1, step= 0.05, value = 0.01)
),
mainPanel(
tabsetPanel( id="tabs",
tabPanel("Exponential Smoothing",
value="panel",
plotOutput(outputId = "es1",
width = "900px",height = "400px"),
dataTableOutput(outputId="infoes"))
))))
server.R
require(shiny)
require(ggplot2)
require(forecast)
require(TTR)
shinyServer(function(input, output, session){
set.seed(123)
predset <- reactive({
tmp <- data.frame(time = 1:100, sales = round(runif(100, 150, 879)) )
tmp.mean <- HoltWinters(x=tmp$sales, alpha = input$alpha, beta = FALSE,gamma=FALSE)
tmp.pred <- data.frame(predict(tmp.mean,n.ahead = input$h, prediction.interval = TRUE), time = tmp[nrow(tmp), "time"] + 1:input$h)
list(tmp = tmp, tmp.pred = tmp.pred)
})
output$es1 <- renderPlot({
tmp <- predset()$tmp
tmp.pred <- predset()$tmp.pred
y <- ggplot(tmp, aes(time, sales)) +
geom_line() +
geom_line(data=tmp.pred, aes(y=upr),color="red") +
geom_line(data=tmp.pred, aes(y=fit),color="blue") +
geom_line(data=tmp.pred, aes(y=lwr),color="red") +
xlab("Days") +
ylab("Sales Quantity")+
ggtitle("title")
y })
output$infoes <- renderDataTable({
predset()$tmp.pred
})
})
Example might look long but it's really simple.
My issue is around having a reactive object and the use of <<-.
I have another shiny app which works great using:
blah <- reactive({
dat <<- etcetc
)
And then successfully using dat later in dataTable and plot components. But with the below I'm failing hard.
Question: What is the difference between item1 <- reactive({etc}) and item2 <<- etc
As I understand it, you can put a reactive dataset into an object (item1) and then use it later by putting item1() in your code. The scoping rules suggest you can use item2 <<- etc and then just use item2 later in your code.
contents2 <- reactive({
datp <- data.frame(mean = c(r1, r2),
chosen = c(rep("A", length(r1)), rep("B", length(r2))))
datp
})
I know I can break up my code below into the form above (with datp and datci being their own reactive objects (say contents2 and contents3), and it works) but shouldn't the scoping <<- below work?
Example:
library(ggplot2)
ui <- navbarPage("Test",
tabPanel("Panel A",
sidebarLayout(
sidebarPanel(
sliderInput("n1", "N sample 1:",
min=2, max=30, value=3),
sliderInput("n2", "N sample 2:",
min=2, max=30, value=3),
numericInput("mean1", label = h5("Mean 1"), value = 100),
numericInput("mean2", label = h5("Mean 2"), value = 80),
numericInput("sd1", label = h5("Std Dev 1"), value = 10),
numericInput("sd2", label = h5("Std Dev 2"), value = 10),
radioButtons("cilevel", "Confidence Interval",
c("99%" = 0.99,
"95%" = 0.95,
"90%" = 0.90),
selected = 0.95)
)
,
mainPanel(
plotOutput("plot")
)
)
),
tabPanel("Panel B",
sidebarLayout(
sidebarPanel(
)
,
mainPanel(
)
)
)
)
server <- function(input, output, session) {
contents1 <- reactive({
r1 <- rnorm(input$n1, input$mean1, input$sd1)
r2 <- rnorm(input$n2, input$mean2, input$sd2)
# Note the change to << now
cimult <<- qt(as.numeric(input$cilevel)/2 + .5, length(r1))
datp <<- data.frame(mean = c(r1, r2),
chosen = c(rep("A", length(r1)), rep("B", length(r2))))
datci <<- data.frame(mean = c(mean(r1), mean(r2)),
sd = c(sd(r1), sd(r2)),
n = c(length(r1), length(r2)),
se = c(sd(r1)/sqrt(length(r1)), sd(r2)/sqrt(length(r2))),
chosen = c("A", "B"))
})
output$plot <- renderPlot({
ggplot(datci, aes(x = factor(chosen),
y = mean)) +
geom_errorbar(aes(ymin = mean - cimult * se,
ymax = mean + cimult * se,
color = factor(chosen))) +
geom_point(aes(color = factor(chosen)), alpha = 0.8) +
geom_point(data = contents1(), alpha = 0.8) +
coord_flip()
})
}
shinyApp(ui = ui, server = server)