how to update a dataset in R shiny - r

Can I get help on how to get the below code to work? I am looking to update the numbers in
dataExample <- getDataset(n1 = c(20),n2 = c(20), means1 = c(18), means2 = c(9),stds1 = c(14), stds2 = c(14))
based on input values and then generate the plot whenever I apply changes but not sure how to do it. I read it somewhere it says need to use reactive or observe but I am not sure how to modify the code?
library(shiny)
library(plyr)
library(rmarkdown)
library(rpact)
design <- getDesignGroupSequential(kMax = 2, alpha = 0.05, informationRates = c(0.5, 1), typeOfDesign = "WT", deltaWT = 0.5)
ui <- fluidPage(
titlePanel("Efficacy Monitoring Using Conditional Power"),
sidebarLayout(
sidebarPanel(
numericInput('nn1', 'Number of Subjects at Current stage (Active)', 20, min = 1, max = 100),
numericInput('nn2', 'Number of Subjects at Current stage (Control)', 20, min = 1, max = 100),
textInput('Mean1', 'Mean1',"18"),
textInput('Mean2', 'Mean2',"9"),
textInput('SD1', 'SD1',"14"),
textInput('SD2', 'SD2',"14"),
textInput('nPlanned', 'Additional Numbers Planned',"40"),
submitButton(text = 'Apply Changes')
),
# Main panel for displaying outputs ----
mainPanel(plotOutput("plot2")
)
)
)
server <- function(input,output){
dataExample <- getDataset(
n1 = c(20),
n2 = c(20),
means1 = c(18),
means2 = c(9),
stds1 = c(14),
stds2 = c(14)
)
stageResults <- getStageResults(design, dataExample,thetaH0 = 0)
output$plot2<-renderPlot(
plot(stageResults, nPlanned = c(as.numeric(input$nPlanned)), thetaRange = c(0, 20))
)
}
# Run the app ----
shinyApp(ui, server)

Use a reactive function and put the input values
library(shiny)
library(plyr)
library(rmarkdown)
library(rpact)
design <- getDesignGroupSequential(kMax = 2, alpha = 0.05, informationRates = c(0.5, 1), typeOfDesign = "WT", deltaWT = 0.5)
ui <- fluidPage(
titlePanel("Efficacy Monitoring Using Conditional Power"),
sidebarLayout(
sidebarPanel(
numericInput('nn1', 'Number of Subjects at Current stage (Active)', 20, min = 1, max = 100),
numericInput('nn2', 'Number of Subjects at Current stage (Control)', 20, min = 1, max = 100),
# WHY THE CHOICE OF textInput instead of numericInput ?
textInput('Mean1', 'Mean1',"18"),
textInput('Mean2', 'Mean2',"9"),
textInput('SD1', 'SD1',"14"),
textInput('SD2', 'SD2',"14"),
textInput('nPlanned', 'Additional Numbers Planned',"40"),
submitButton(text = 'Apply Changes')
),
# Main panel for displaying outputs ----
mainPanel(plotOutput("plot2")
)
)
)
server <- function(input,output){
# Use the input values in a reactive function
dataExample <- reactive({
getDataset(
n1 = input$nn1,
n2 = input$nn2,
means1 = as.numeric(input$Mean1),
means2 = as.numeric(input$Mean2),
stds1 = as.numeric(input$SD1),
stds2 = as.numeric(input$SD2)
)
})
output$plot2<-renderPlot({
stageResults <- getStageResults(design, dataExample(), thetaH0 = 0)
plot(stageResults, nPlanned = c(as.numeric(input$nPlanned)), thetaRange = c(0, 20))
})
}
# Run the app ----
shinyApp(ui, server)

Related

R Shiny: actionButton to generate random value from input values and render plot

I have made a simple shiny app that generates a plot of the x and y data from an individual group within the data which the users can choose from. The app subsets the larger dataframe and produces the graph for only the chosen individual. I would also like to include and actionButton which chooses an individual from within the dataset at random and plots that every time the button is pushed.
library(shiny)
library(tidyverse)
# Create example data frame
Data <- data.frame(Indiv = c(rep(1,10),
rep(2,10),
rep(3,10),
rep(4,10),
rep(5,10),
rep(6,10)),
varX = c(runif(10, min = 1, max = 10),
runif(10, min = 1, max = 10),
runif(10, min = 1, max = 10),
runif(10, min = 1, max = 10),
runif(10, min = 1, max = 10),
runif(10, min = 1, max = 10)),
varY = c(runif(10, min = 1, max = 1),
runif(10, min = 1, max = 5),
runif(10, min = 1, max = 10),
runif(10, min = 1, max = 15),
runif(10, min = 1, max = 20),
runif(10, min = 1, max = 25))
)
###### Shiny App #######
# User interface for shiny app
ui <- fluidPage(
titlePanel("Random Select Button"), # page title
sidebarLayout(
# Sidebar panel
sidebarPanel(
# input for which TagID to display in plot
actionButton("do", "Plot Random Indiv"),
selectInput(inputId = "ID",
label = "Individual ID",
choices = levels(factor(Data$Indiv)),
selected = NULL, # choose no individuals by default
multiple = FALSE # allow for multiple options
),
p("Choose an invidual, or push the button to randomly choose an individual."),
),
# Main Panel
mainPanel(
plotOutput("IndivPlot"), # name of plot object
),
)
)
# Server
server <- function(input, output) {
# Plot
output$IndivPlot <- renderPlot({ # make a live adjustable plot
### Filter to only include selected Individual
Data <- Data[Data$Indiv %in% input$ID,]
# Create plot
p = ggplot(data=Data, aes(x=varX, y=varY))+
geom_line()+
expand_limits(y=c(1,30), x = c(1,10))+
scale_y_continuous(breaks=seq(1,30,5), labels=seq(1,30,5))+
scale_x_continuous(breaks = seq(1,10,1), labels = seq(1,10,1))+
labs(x = "My X", y = "My Y")
print(p)
})
}
shinyApp(ui = ui, server = server)
I can't figure out how to get the action button to randomly choose and individual ID number and cause the plot to render. Right now, the button exists on the UI but doesn't do anything.
You may create a reactive ID which will be dynamic. It will be updated when the ID is selected from the dropdown as well as when the action button is pressed to generate random ID.
The plot will be updated based on the ID.
library(shiny)
library(tidyverse)
###### Shiny App #######
# User interface for shiny app
ui <- fluidPage(
titlePanel("Random Select Button"), # page title
sidebarLayout(
# Sidebar panel
sidebarPanel(
# input for which TagID to display in plot
actionButton("do", "Plot Random Indiv"),
selectInput(inputId = "ID",
label = "Individual ID",
choices = levels(factor(Data$Indiv)),
selected = NULL, # choose no individuals by default
multiple = FALSE # allow for multiple options
),
p("Choose an invidual, or push the button to randomly choose an individual."),
),
# Main Panel
mainPanel(
plotOutput("IndivPlot"), # name of plot object
),
)
)
# Server
server <- function(input, output, session) {
#To save dynamic ID
rv <- reactiveValues()
observe({
#ID selected from the dropdown manually
rv$ID <- input$ID
})
# Plot
output$IndivPlot <- renderPlot({ # make a live adjustable plot
### Filter to only include selected Individual
Data <- Data[Data$Indiv %in% rv$ID,]
# Create plot
p = ggplot(data=Data, aes(x=varX, y=varY))+
geom_line()+
expand_limits(y=c(1,30), x = c(1,10))+
scale_y_continuous(breaks=seq(1,30,5), labels=seq(1,30,5))+
scale_x_continuous(breaks = seq(1,10,1), labels = seq(1,10,1))+
labs(x = "My X", y = "My Y")
print(p)
})
#On action button click
observeEvent(input$do, {
#Select a random ID
rv$ID <- sample(unique(Data$Indiv), 1)
#Update the value of dropdown with random ID selected
updateSelectInput(session, inputId = "ID",
label = "Individual ID",
choices = levels(factor(Data$Indiv)),
selected = rv$ID)
})
}
shinyApp(ui = ui, server = server)

Shiny feedbackDanger doesnt work inside eventReactive where function is called

I am begginer in shiny an I am stucked adding feedback in my app.
I have tried a few things like write this code inside the eventReactive function like use the function feedBackDanger.
Below, there is a simplified full code with the ui, the idea is that i need the user get some Error (but not the console Error) if he set 'zero' in kind variable when mean is 3,6 or 9.
Also the actionButton 'simulate' should be disable when this condition is selected.
ui <- shinyUI(fluidPage(
titlePanel(h1("Simulation", align = 'center')),
sidebarLayout(
sidebarPanel(
numericInput(inputId = "n", label = "Size of Sample", min = 1,
step = 1, value = 1),
numericInput(inputId = "mean", label = "Mean of Sample", min = 1,
step = 1, value = 1),
numericInput(inputId = "var", label = "Variance", min = 1,
step = 0.25, value = 1),
radioButtons("kind", "Sample kind", choices = c("two", "zero")),
actionButton("simulate", "Simulate"),
width = 200
),
mainPanel(
plotOutput("distPlot", width = 500, height = 500)
)
)
))
# Define server logic required to draw a histogram
server <- shinyServer(function(input, output, session) {
s_fin <-function(n,
mean,
var,
kind){
a <- rnorm(n, mean, var)
if(kind == 'two'){
a <- a + 2
}
if(kind == 'zero'& mean %in% c(3,6,9)){
print('ERROR: function error')
stop(call. = T)}
return(a)
}
simulation <- eventReactive(input$simulate,{
s_fin(n = input$n,
mean = input$mean,
var = input$var,
kind = input$kind)
})
output$distPlot <- renderPlot({
hist(simulation())
})
})
shinyApp(ui, server)
The next code works to me (a just add useShinyFeedback() in ui.R, and put the error function instead of print):
library(shinyFeedback)
ui <- shinyUI(fluidPage(
useShinyFeedback(),
titlePanel(h1("Simulation", align = 'center')),
sidebarLayout(
sidebarPanel(
numericInput(inputId = "n", label = "Size of Sample", min = 1,
step = 1, value = 1),
numericInput(inputId = "mean", label = "Mean of Sample", min = 1,
step = 1, value = 1),
numericInput(inputId = "var", label = "Variance", min = 1,
step = 0.25, value = 1),
radioButtons("kind", "Sample kind", choices = c("two", "zero")),
actionButton("simulate", "Simulate"),
width = 200
),
mainPanel(
plotOutput("distPlot", width = 500, height = 500)
)
)
))
# Define server logic required to draw a histogram
server <- shinyServer(function(input, output, session) {
s_fin <-function(n,
mean,
var,
kind){
a <- rnorm(n, mean, var)
if(kind == 'two'){
a <- a + 2
}
if(kind == 'zero'& mean %in% c(3,6,9)){
showFeedbackDanger(
inputId = "mean",
text = "Not use mean 3, 6 or 9"
)
shinyjs::disable("simulate")
}else{
hideFeedback("mean")
shinyjs::enable("simulate")
}
return(a)
}
simulation <- eventReactive(input$simulate,{
s_fin(n = input$n,
mean = input$mean,
var = input$var,
kind = input$kind)
})
output$distPlot <- renderPlot({
hist(simulation())
})
})
shinyApp(ui, server)

Topic Modelling Visualization using LDAvis and R shinyapp and parameter settings

I am using LDAvis in R shiny app.
Here is the code and it works without errors.
# docs is a csv file with a "text" column, e.g.
# docs <- read.csv("docs.csv",sep=",",header=TRUE)
ui <- navbarPage(
title = "NLP app",
tabPanel("Topic Model",icon = icon("group"),
fluidPage(
headerPanel(""),
titlePanel(p(h2("Topic Modelling example",style = "color:#4d3a7d"))),
#sidebarPanel(
wellPanel(tags$style(type="text/css", '#leftPanel { width:200px; float:left;}'), style = "background: lightgrey",
id = "leftPanel",
sliderInput("nTopics", "Number of topics to display", min = 5, max = 50, value = 10, step=5),
sliderInput("nTerms", "#top terms per topic", min = 10, max = 50, value = 20, step=5),
tags$hr(),
actionButton(inputId = "GoButton", label = "Go", icon("refresh"))
),
mainPanel(
tabPanel("Topic Visualisation", hr(),helpText(h2("Please select a topic!")), visOutput('visChart')))
)
)
)
# server
server <- function(input, output, session) {
Topic_Subset <- reactive({
docs <- docs$text
nTopics <- input$nTopics
# topic model using text2vec package
tokens = docs %>%
tolower %>%
word_tokenizer
it = itoken(tokens, progressbar = FALSE)
v = create_vocabulary(it,stopwords=tm::stopwords("en"))
vectorizer = vocab_vectorizer(v)
dtm = create_dtm(it, vectorizer, type = "dgTMatrix")
lda_model = text2vec::LDA$new(n_topics = nTopics, doc_topic_prior = 0.1, topic_word_prior = 0.01)
lda_model$fit_transform(x = dtm, n_iter = 1000,
convergence_tol = 0.001, n_check_convergence = 25,
progressbar = FALSE)
return(lda_model) #
})
output$visChart <- renderVis({
input$GoButton
isolate({
nterms <- input$nTerms
lda_model <- Topic_Subset()
})
lda_model$plot(out.dir = "./results", R = nterms, open.browser = FALSE)
readLines("./results/lda.json")
})
}
shinyApp(ui = ui, server = server)
I would like to see whether it is possible to use width = "80%" in visOutput('visChart') similar to, for example, wordcloud2Output("a_name",width = "80%"); or any alternative methods to make the size of visualization smaller. Particularly, when I minimize the shiny app window, the plot does not fit in the page. My second question is: how can I initialize the parameter lambda (please see the below image and yellow highlights) with another number like 0.6 (not 1)?

R Shiny animation scatterplot speed performance

I want to make an animation in R Shiny where my scatter plot is progressively updated at each iteration, here is my current plot
library(shiny)
library(plotly)
ui <- fluidPage(
titlePanel(""),
sidebarLayout(
sidebarPanel(
actionButton("launch", "Launch Simulation"),
radioButtons("display","Show every iteration", selected = 10,
choices = c(1,5,10,50),inline = FALSE),
numericInput("iter","Maximum number of iterations", value = 2000,
min = 500,max = 5000, step = 500)
),
mainPanel(
plotlyOutput('plot')
)
)
)
server <- function(input, output) {
rv <- reactiveValues(i = 0,
df = data.frame(x = -1,y = -1))
observeEvent(input$launch,{
rv$i = 0
rv$df = data.frame(x = runif(5000, min = -1,max = 1),
y = runif(5000, min = -1,max = 1))
})
observe({
isolate({
rv$i = rv$i + as.numeric(input$display)
})
if ((rv$i < input$iter)&input$launch){
invalidateLater(0)
}
})
output$plot <- renderPlotly({
df = data.frame(x = 0,y = -1)
df = rbind(df,rv$df)
plot_ly(df[1:(rv$i + 1),], x = ~x, y = ~y,
type = 'scatter', mode = 'markers',
marker = list(size = 4), hoverinfo="none") %>%
layout(showlegend = FALSE)
})
}
shinyApp(ui = ui, server = server)
The code is working fine at the beginning but after around 1000 iterations, the animation becomes very slow. I think the main problem is that because in my code, I have to re-make the plot all over again at each iteration, is there a smoother way to do what I want to do?
(Not necessarily with Plotly but it is important to me that I keep track of the number of the iterations outside of the plot (here rv$i))

Interdependent widgets in Shiny ui

I am running the current version of RStudio, R, and all R packages.
In the sample code below, my goal is to set the maximum value for the xcol and ycol so they are limited to the number of columns in the dataframe that is being plotted. The code below results in the error "object 'input' not found." I suspect the problem may be that I am making the widgets in the ui dependent, but that is a guess on my part. Is that the problem, and is there a strategy that I can use to get around it.
I reviewed posts that contained the same error, but couldn't find anything that answered my question (or didn't recognize when it was answered.) The closest posts to my issue were: R Shiny error: object input not found; R Shiny renderImage() does not recognize object 'input'; Error in eval: object 'input' not found in R Shiny app; Conditional initial values in shiny UI?
Here is some reproducible code with random data.
library(tidyverse)
library(cluster)
library(vegan)
library(shiny)
dta <- rnorm(100, mean = 0, sd = 1)
mat <- matrix(dta, nrow = 10)
dm <- daisy(mat, metric = "euclidean") %>% as.matrix()
server <- function(input, output) {
output$plot <- renderPlot({
nmds <- metaMDS(dm, distance = "euclidean", k = input$dim, trymax = 2000, autotransform = FALSE, noshare = FALSE, wascores = FALSE)
df <- nmds$points %>% as.data.frame()
plot(df[,input$xcol], df[,input$ycol])
}, height = 500, width = 500)
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput("dim", "Number of dimensions", value = 2, min = 2, max = 12),
numericInput("xcol", "X column", value = 1, min = 1, max = input$dim),
numericInput("ycol", "Y column", value = 2, min = 1, max = input$dim)
),
mainPanel(
plotOutput("plot")
)
)
)
You can use updateNumericInput to modify the UI from the server:
# Modify ui to use initial max
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput("dim", "Number of dimensions", value = 2, min = 2, max = 12),
numericInput("xcol", "X column", value = 1, min = 1, max = 2),
numericInput("ycol", "Y column", value = 2, min = 1, max = 2)
),
mainPanel(
plotOutput("plot")
)
)
)
# Modify server to update max when dim changes
# (notice the session parameter needed for updateNumericInput)
server <- function(input, output, session) {
output$plot <- renderPlot({
if(input$xcol>input$dim)
updateNumericInput(session, "xcol", value=input$dim, max=input$dim)
else
updateNumericInput(session, "xcol", max=input$dim)
if(input$ycol>input$dim)
updateNumericInput(session, "ycol", value=input$dim, max=input$dim)
else
updateNumericInput(session, "ycol", max=input$dim)
nmds <- metaMDS(dm, distance = "euclidean", k = input$dim, trymax = 2000, autotransform = FALSE, noshare = FALSE, wascores = FALSE)
df <- nmds$points %>% as.data.frame()
plot(df[,min(input$dim,input$xcol)], df[,min(input$dim,input$ycol)])
}, height = 500, width = 500)
}

Resources