I'm just starting out on Shiny and have been working with a dataset to try and get some experience. I've reworked a simple code for quite a few iterations and keep getting the ...argument is missing with no default. Does anyone see what I'm missing?
ui.R
=============================
library(shiny)
shinyUI(
pageWithSidebar(
headerPanel("Simple Cluster Example"),
sidebarPanel(
numericInput("var", "Cluster:", 2,
min = 2, max = 5, step = 1)),
mainPanel(
plotOutput("plot"),
#dataTableOutput("table")
)
)
)
-------------------------------
server.R
===============
library('shiny')
library('ggplot2')
shinyServer(function(input, output) {
protein <- read.csv("protein.csv")
vars.to.use <- colnames(protein) [-1]
pmatrix <- scale(protein[,vars.to.use])
pcenter <- attr(pmatrix, "scaled:center")
pscale <- attr(pmatrix, "scaled:scale")
d <- dist(pmatrix, method="euclidean")
pfit <- hclust(d, method="ward.D")
# This code is triggered whenever the drop-down menu is changed in the UI
component <- input$var
#rect.hclust(pfit, k=component)
groups <- cutree(pfit, k=component)
princ <- prcomp(pmatrix)
nComp <- 2
project <- predict(princ, newdata=pmatrix) [,1:nComp]
project.plus <- cbind(as.data.frame(project),
cluster=as.factor(groups),
country=protein$Country)
p <- ggplot(project.plus, aes(x=PC1, y=PC2)) +
geom_point(aes(shape=cluster))+geom_text(aes(label=country), hjust=0, vjust=1)
output$plot <- renderPlot({print(p)})
})
Your problem is:
plotOutput("plot"),
When you end with "," (since you commented out the line after) it expects a new argument. But it is empty in your case, so remove the extra ",".
Related
I'm new to shiny and I'm trying to use it for a simulation of a prey/predator model.
First, I wanted to generate the dataframe with all the initial positions for each animal; and try to plot it usign ggplot; but when I hit the actionButton, the plot never showed. I dont interstand why and there is any error message to let me at least know what is wrong.
Here is the code:
library(shiny)
library(tidyverse)
library(ggplot2)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("nPrey", "select total number of preys", 1, 100, 10, 1),
sliderInput("nHunter", "select total number of Hunters", 1, 100, 10, 1),
actionButton ("play", "Begin simulation")
),
mainPanel(
plotOutput("plot")
)
)
)
server <- function(input, output, session) {
zMax = 20
simulation <- eventReactive(input$play, {
createInitialTable(input$nPrey, input$nHunter)
})
output$plot <- renderPlot({
p <- ggplot() +
geom_point(aes_string(x="X",y="Y"), data=simulation()) +
coord_cartesian(xlim =c(0, zMax), ylim = c(0, zMax))
})
createInitialTable <- function (nPrey, nHunter){
aAnimal <- data.frame()
cVar <- c("X", "Y")
for (i in 1:nPrey){
aAnimal <- rbind(aAnimal, c(round(runif(1)*zMax), round(runif(1)*zMax)))
}
for (i in 1:nHunter){
aAnimal <- rbind(aAnimal, c(round(runif(1)*zMax), round(runif(1)*zMax)))
}
colnames(aAnimal) <- cVar
return (aAnimal)
}
}
shinyApp(ui, server)
Thank you for reading this
Simple fix: Remove p <- and you should be good to go. However, to improve you need to check the reactivity of your execution when the nPrey and Hunter are dynamically changing.
I want to create a small shiny app to explore a scoring function that I am writing for a set of data observations. This is my first shiny app so bear with me.
What I want to show is the data table where one column is computed by a function (let's say f(x) = x^2 + y) where x is another (numeric) column in the table and y should be adjustable with a slider in the sidebar.
I want to make the table reactive, so that as soon as the slider is adjusted, the content that is displayed will be updated. Does anyone have a link to a tutorial (I could not find a similar problem) or a suggestion how to handle this. If so, please let me know!
This is the code I have so far:
library(shiny)
#### INIT ####
x <- 1
y <- 0.5
z <- 2
df <- data.frame(
a=1:10,
b=10:1
)
df['score'] <- df[,x]^y + z
#### UI ####
ui <- fluidPage(
title = "Examples of DataTables",
sidebarLayout(
sidebarPanel(
sliderInput("x", "x:",
min = 0, max = ncol(df),
value = 1),
sliderInput("y", "y:",
min = 1, max = 10,
value = 1),
sliderInput("z", "z:",
min = 1, max = 100,
value = 20)
),
mainPanel(
tabsetPanel(
id = 'dataset',
tabPanel("df", dataTableOutput("df"))
)
)
)
)
#### SERVER ####
server <- function(input, output) {
sliderValues <- reactive({
df['score'] <- df[,input$x]^input$y + input$z
})
sliderValues()
output$df<- renderDataTable(df)
}
#### RUN ####
shinyApp(ui = ui, server = server)
Just make the data.frame you actually plot reactive. For example
server <- function(input, output) {
calcualtedValues <- reactive({
df['score'] <- df[,input$x]^input$y + input$z
df
})
output$df<- renderDataTable(calcualtedValues())
}
Here the calcualtedValues reactive element returns a new data.frame when the input is updated, and then you actually render that updated data.frame rather than the original data.frame each time.
I've looked through R Shiny tutorials and stackoverflow for answers related to my query. I usually wait for 3-4 days to solve a coding problem before I attempt to post.
I have an animated slider in my UI that loops through time interval in a column (column a) . I'm trying to produce an animated line plot that plots y values of another column (column b), corresponding to the nrow() of that time interval. The slider works perfectly, but I haven't been able to plot the output.
I mightve missed some concepts related to reactivity in Shiny app. Appreciate any guidance I can get related to my query. I'll be happy to post more info if needed.
a <- c(0,1,2,3,4,5,6)
b <- c(50,100,40,30,20,80)
mydata <- cbind(a,b)
mydata <- as.data.frame(mydata())
ui <- fluidPage (
headerPanel("basic app"),
sidebarPanel(
sliderInput("slider",
label = "Time elapsed",
min = 0,
max = nrow(mydata()),
value = 1, step = 1,
animate =
animationOptions(interval = 200, loop = TRUE))
),
mainPanel(
plotlyOutput("plot")
)
)
server <- function(input, output) {
sliderValues <- reactive({
data.frame(
Name = "slider",
Value = input$slider)
})
output$plot <- renderPlot({
x<- as.numeric(input$slider)
y <- as.numeric(b[x])
ggplot(mydata,aes_string(x,y))+ geom_line()
})
}
Just as a demo, I wanted the animated plot to come out like this, but in correspondance to UI slider values :
library(gganimate)
library(ggplot2)
fake <- c(1,10)
goods <- c(11,20)
fakegoods <- cbind(fake,goods)
fakegoods <- data.frame(fakegoods)
ggplot(fakegoods, aes(fake, goods)) + geom_line() + transition_reveal(1, fake)
Does this accomplish what you are looking for? Note that I removed the first element, 0, from vector a as your original example had more elements in a than b, and in order for them to be cbind together they must be the same length.
library(ggplot2)
library(shiny)
a <- c(1,2,3,4,5,6)
b <- c(50,100,40,30,20,80)
mydata <- cbind(a,b)
mydata <- as.data.frame(mydata)
ui <- fluidPage (
headerPanel("basic app"),
sidebarPanel(
sliderInput("slider",
label = "Time elapsed",
min = min(mydata$a),
max = max(mydata$a),
value = min(mydata$a), step = 1,
animate =
animationOptions(interval = 200, loop = TRUE))
),
mainPanel(
plotOutput("plot")
)
)
server <- function(input, output) {
output$plot <- renderPlot({
plotdata <- mydata[1:which(input$slider==mydata$a),]
p <- ggplot(plotdata,aes(x = a,y = b))
if(nrow(plotdata)==1) {
p + geom_point()
} else {
p + geom_line()
}
})
}
I have a problem. I want to use sidebar to curb time series plot, however, I get invalid formula error when trying to do the plot. Can someone pls help?
server.r
library(shiny)
library(BCA)
data(Eggs)
# Define server logic required to plot
shinyServer(function(input, output) {
formulaX <- reactive({
tmp <- paste(input$range,collapse = ":")
paste("Eggs[",tmp,",1]")
})
formulaY <- reactive({
tmp1 <- paste(input$range,collapse = ":")
paste("Eggs[",tmp1,",5]")
})
# Return the formula text for printing as a caption
output$caption <- renderText({
paste(formulaX(),formulaY(),sep = " ")
})
#creating plot -ERROR
output$mpgPlot <- renderPlot({
plot(as.formula(formulaX()),as.formula(formulaY()))
})
})
ui.r
library(shiny)
# Define UI
shinyUI(pageWithSidebar(
# Application title
headerPanel("Eggs"),
sidebarPanel(
# Specification of range within an interval
sliderInput("range", "Range:",
min = 1, max = 105, value = c(20,50))
),
mainPanel(
h3(textOutput("caption")),
plotOutput("mpgPlot")
)
))
"Eggs[1:10,1]" is not a formula, it is a character-representation of a subset. Since you are always choosing columns 1 and 5, your "formula" is always "Cases ~ Week" (I don't have BCA installed, I think that's correct), and you are intending to use a subset of rows from the data.
Perhaps this would work instead (hasty, some programming safeguards would be appropriate):
# no need for formulaX(), formulaY()
# not certain what you want/need from output$caption
dataX <- reactive({ Eggs[input$range[1]:input$range[2],,drop = FALSE] })
and your plot:
output$mpgPlot <- renderPlot({
plot(Cases ~ Week, data = dataX())
})
or
output$mpgPlot <- renderPlot({
x <- dataX()
plot(x$Week, x$Cases)
})
I am trying to displaying different 3D plots in different tab panels, but I found that 3D plot only displayed in the first tab panel. According to this post, plotOutputs parameter outputId should be unique, and in my case IDs are unique over the entail shiny app. Some lines of my app are as follow:
ui.R
shinyUI(fluidPage(
mainPanel(
tabsetPanel(
tabPanel("VWC", webGLOutput("VWC3DPlot")),
tabPanel("TEMP", webGLOutput("TEMP3DPlot"))
)
)
))
server.R
shinyServer(function(input, output) {
# set dir;
dataDir <- "C:/Users/PH/Desktop/data/DATA/"
# store dataframe of attribute to list;
dfList <- readIntoDF(dataDir) # readIntoDF() is function that return a list
# extract dataframe from list
dfVWC <- dfList$VWC
dfTEMP <- dfList$TEMP
# processing of dataframes
dfVWC <- transformDF(dfVWC)
dfTEMP <- transformDF(dfTEMP)
# prepare grid for kriging;
grd <- expand.grid(x=seq(from=0, to=600, by=200),
y=seq(from=0, to=500, by=200))
# Kriging;
dfVWCkrige <- krigingFun(dfVWC, grd)
dfTEMPKrige <- krigingFun(dfTEMP, grd)
krigeList <- list("VWCKrige" = dfVWCkrige, "TEMPKrige" = dfTEMPKrige)
return(krigeList)
}) # end of dataInput
### create cubs;
output$VWC3DPlot <- renderWebGL({
createCubes(dataInput()$VWCKrige) # createCubes() is a function that use output of kriging and shinyrgl pkg to create cubes;
})
output$TEMP3DPlot <- renderWebGL({
createCubes(dataInput()$TEMPKrige)
})
})
Since there are hundreds of lines, I could not to post all of them.
According to this post, I updated the version of shiny, but had no effect on my case.
You appear to be using shinyRGL. Don't use it, rgl has what you need. Here's an example that works for me:
ui.R:
library(shiny)
shinyUI(fluidPage(
mainPanel(
tabsetPanel(
tabPanel("red",
rglwidgetOutput('thewidget1')),
tabPanel("green",
rglwidgetOutput('thewidget2'))
))
))
server.R:
library(shiny)
library(rgl)
options(rgl.useNULL = TRUE)
shinyServer(function(input, output, session) {
x <- rnorm(100)
y <- 2*rnorm(100)
z <- 10*rnorm(100)
open3d()
plot3d(x, y, z, col = "red")
scene1 <- scene3d()
plot3d(z, y, x, col = "green")
scene2 <- scene3d()
rgl.close()
save <- options(rgl.inShiny = TRUE)
on.exit(options(save))
output$thewidget1 <- renderRglwidget(
rglwidget(scene1)
)
output$thewidget2 <- renderRglwidget(
rglwidget(scene2)
)
})
By the way, we would have got here a lot sooner if you had posted a reproducible example as requested.