I have the following shiny app, which consists of a numeric input and as outputs two ggplot-graphics.
library(shiny)
n <- 100
dat <- data.frame(var1 = round(rnorm(n, 50, 10),0),
var2 = sample(c("A", "B"), n, replace = TRUE))
# USER INTERFACE
ui <- fluidPage(
titlePanel("My Sample App"),
sidebarLayout(
sidebarPanel(
numericInput("n", "Number of cases", value=100)
),
mainPanel(
plotOutput("boxplot"),
plotOutput("distribution")
)
)
)
# SERVER
server <- function(input, output) {
output$boxplot <- renderPlot({
ggplot(data = dat, aes(x = var2, y = var1)) + geom_boxplot() + ggtitle("Boxplot")
})
output$distribution <- renderPlot({
ggplot(data = dat, aes(var1)) + geom_histogram() + ggtitle("Histogram")
})
}
# Run the application
shinyApp(ui = ui, server = server)
I've been trying to replace n = 10 with n = input$n. However it didn't work and I am unsure, where exactly I have to define the data.frame (inside the server function?). Can someone help please?
input$n is a reactive variable that can only be used in a reactive context. You can only define a reactive context in the server function, e.g. using reactive. Have a look here for an explanation.
library(shiny)
library(ggplot2)
# USER INTERFACE
ui <- fluidPage(
titlePanel("My Sample App"),
sidebarLayout(
sidebarPanel(
numericInput("n", "Number of cases", value=100)
),
mainPanel(
plotOutput("boxplot"),
plotOutput("distribution")
)
)
)
# SERVER
server <- function(input, output) {
dat <- reactive({
data.frame(var1 = round(rnorm(input$n, 50, 10),0),
var2 = sample(c("A", "B"), input$n, replace = TRUE))
})
output$boxplot <- renderPlot({
ggplot(data = dat(), aes(x = var2, y = var1)) + geom_boxplot() + ggtitle("Boxplot")
})
output$distribution <- renderPlot({
ggplot(data = dat(), aes(var1)) + geom_histogram() + ggtitle("Histogram")
})
}
# Run the application
shinyApp(ui = ui, server = server)
Related
I'm new in programming language especially R.
I have data frame and want to show top 3 of my data and sort from the biggest value using bar chart. I have tried some codes but failed to create proper chart. Here is my latest code :
library(shiny)
library(plotly)
my_data <- data.frame(x1 = c("a","b", "c","d","e","f","g","h"),
x2 = c(200, 200, 100,200,200,100,200,100),
x3 = c(100,400,500,50,100,300,100,50))
df1 <- my_data[order(my_data$x3),] #order by x3 value, to create rank
ui <- tabPanel("Test",
sidebarLayout(
sidebarPanel(
selectInput(inputId = "why",
label = "1. Select",
choices = df1$x2),
),
mainPanel(plotlyOutput("test"))
))
server <- function(input, output, session) {
output$test <- renderPlotly({
df2 <- df1 %>%
filter(x2 ==input$why) #filter by x2
p <-ggplot(df2,
aes(x = x1, y=x3)) +
geom_bar(stat = "identity")
fig <- ggplotly(p)
fig
})}
shinyApp(ui = ui, server = server)
the bar chart I created was not ordered correctly (based on x3 values), and I also only want to show top 3 of my data
To filter for the top 3 rows you could use dplyr::slice_max and to reorder your bars use e.g. reorder. Simply reordering the dataset will not work.
library(shiny)
library(dplyr)
library(plotly)
ui <- tabPanel(
"Test",
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "why",
label = "1. Select",
choices = unique(df1$x2),
selected = 200
),
),
mainPanel(plotlyOutput("test"))
)
)
server <- function(input, output, session) {
output$test <- renderPlotly({
df2 <- df1 %>%
filter(x2 == input$why) %>%
slice_max(x3, n = 3, with_ties = FALSE)
p <- ggplot(
df2,
aes(x = reorder(x1, -x3), y = x3)
) +
geom_bar(stat = "identity")
fig <- ggplotly(p)
fig
})
}
shinyApp(ui = ui, server = server)
#>
#> Listening on http://127.0.0.1:8022
I know the question is already answered, but I encourage you to keep your server function as small as possible and try to wrap long series of code into functions.
Here is an example of what I mean
library(tidyverse)
library(shiny)
library(plotly)
my_data <- data.frame(x1 = c("a","b", "c","d","e","f","g","h"),
x2 = c(200, 200, 100,200,200,100,200,100),
x3 = c(100,400,500,50,100,300,100,50))
df1 <- my_data[order(my_data$x3),] #order by x3 value, to create rank
myPlot <- function(data, input) {
df <- data |>
filter(x2 == input) #filter by x2
p <-ggplot(df, aes(x = reorder(x1, -x3), y=x3)) +
geom_bar(stat = "identity")
return(ggplotly(p))
}
ui <- tabPanel("Test",
sidebarLayout(
sidebarPanel(
selectInput(inputId = "why",
label = "1. Select",
choices = df1$x2),
),
mainPanel(plotlyOutput("test"))
))
server <- function(input, output, session) {
output$test <- renderPlotly({
myPlot(df1, input$why)
})
}
shinyApp(ui = ui, server = server)
I want to get the following simple R function running in Shiny.
It works fine in R.
LifeExpectancy <- function(Age){
X <- which(lifeExpCH$Alter == Age)
LifeE <- lifeExpCH$`2018`[X:100]
Y <- seq(Age, 99, 1)
df1 <- data.frame(LifeE, Y)
ggplot(df1, aes(Y, LifeE)) +
geom_line() +
labs(x = “Age”, y = “Years Expected to Live”, title = “Life Expectancy Switzerland 2018”)
}
What I wrote in Shiny and is not working.
Would very be very happy for some help, thank you.
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput(inputId = "Age", label = "Enter your age", value = 30, min = 0, max = 99)
),
mainPanel(
plotOutput(outputID = "LifeExp_plot")
)
)
)
LifeExpectancy <- function(Age){
X <- which(lifeExpCH$Alter == Age)
LifeE <- lifeExpCH$`2018`[X:100]
Y <- seq(Age, 99, 1)
df1 <- data.frame(LifeE, Y)
return(df1)
}
server <- function(input, output){
LifeExpectancy <- reactive ({
LifeExpectancy(input$Age)
})
output$LifeExp_plot <- renderPlot({
ggplot(LifeExpectancy, aes(Y, LifeE) ) +
geom_line()
})
}
shinyApp(ui = ui, server = server)
#Martin - I hope this may be helpful. I am not able to run as I don't have lifeExpCH available.
Note I renamed your calculation function as LifeExpectancyFromAge to distinguish from your reactive function. And when you call your reactive function, make sure to use parentheses.
library(shiny)
library(ggplot2)
LifeExpectancyFromAge <- function(Age){
X <- which(lifeExpCH$Alter == Age)
LifeE <- lifeExpCH$`2018`[X:100]
Y <- seq(Age, 99, 1)
df1 <- data.frame(LifeE, Y)
return(df1)
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput(inputId = "Age", label = "Enter your age", value = 30, min = 0, max = 99)
),
mainPanel(
plotOutput(outputId = "LifeExp_plot")
)
)
)
server <- function(input, output){
LifeExpectancy <- reactive ({
LifeExpectancyFromAge(input$Age)
})
output$LifeExp_plot <- renderPlot({
ggplot(LifeExpectancy(), aes(Y, LifeE)) +
geom_line() +
labs(x = "Age", y = "Years Expected to Live", title = "Life Expectancy Switzerland 2018")
})
}
shinyApp(ui = ui, server = server)
I'd like to include the reactive outputs of two data sets as different geom_lines in the same ggplotly figure. The code runs as expected when only one reactive data.frame is included as a geom_line. Why not two?
ui <- fluidPage(
sidebarLayout(
selectInput("Var1",
label = "Variable", #DATA CHOICE 1
selected = 10,
choices = c(10:100)),
selectInput("Var1",
label = "Variable2", #DATA CHOICE 2
selected = 10,
choices = c(10:100))
# Show a plot of the generated distribution
),
mainPanel(
plotlyOutput('plot') #Draw figure
)
)
server <- function(input, output) {
out <- reactive({
data.frame(x = rnorm(input$Var1), #Build data set 1
y = 1:input$Var1)
})
out2 <- reactive({
data.frame(x = rnorm(input$Var2), #Build data set 2
y = 1:input$Var2)
})
output$plot <- renderPlotly({
p <- ggplot() +
geom_line(data = out(), aes(x = x, y = y)) #Add both data sets in one ggplot
geom_line(data = out2(), aes(x = x, y = y), color = "red")
ggplotly(p)
})
}
# Run the application
shinyApp(ui = ui, server = server)
When you put the data into long format and give each group a group identifier it seems to work. Note that you should be able to change sliderInput back to selectInput - this was one of the entries I toggled during testing, but the choice of UI widget should not matter.
This works -- code can be simplified inside the reactive from here:
library(plotly)
ui <- fluidPage(
sidebarLayout(
sliderInput("Var1",
label = "Variable", #DATA CHOICE 1
min=10, max=100, value=10),
sliderInput("Var2",
label = "Variable2", #DATA CHOICE 2
min=10, max=100, value=10),
),
mainPanel(
plotlyOutput('plot') #Draw figure
)
)
server <- function(input, output) {
out <- reactive({
x1 <- rnorm(input$Var1)
y1 <- seq(1:input$Var1)
x2 <- rnorm(input$Var2)
y2 <- seq(1:input$Var2)
xx <- c(x1,x2)
yy <- c(y1,y2)
gg <- c( rep(1,length(y1)), rep(2,length(y2)) )
df <- data.frame(cbind(xx,yy,gg))
df
})
output$plot <- renderPlotly({
p <- ggplot() +
geom_line(data=out(), aes(x = xx, y = yy, group=gg, colour=gg))
ggplotly(p)
})
}
shinyApp(ui = ui, server = server)
I am new to R and Shiny package. I have a csv file with 4 col and 600 rows and I am trying to plot some graphs using ggplot2.
My ui and server codes are like:
dt<-read.csv('file.csv')
server <- function(input, output) {
output$aPlot <- renderPlot({
ggplot(data = dt, aes(x = Col1, y = Col2, group = 'Col3', color = 'Col4')) + geom_point()
})
}
ui <- fluidPage(sidebarLayout(
sidebarPanel(
sliderInput("Obs", "Log FC", min = 1, max = 600, value = 100)
),
mainPanel(plotOutput("aPlot")) ))
Here, I can get the ggplot output but I don't know how to use this slider input to control the number of rows to be read i.e., I want this "Obs" input to define the size of Col1 to be used in the graph.
Try something like this, example here is with mtcars dataset:
library(shiny)
library(ggplot2)
dt <- mtcars[,1:4]
ui <- fluidPage(
sidebarPanel(
sliderInput("Obs", "Log FC", min = 1, max = nrow(dt), value = nrow(dt)-10)
),
mainPanel(plotOutput("aPlot"))
)
server <- function(input, output) {
mydata <- reactive({
dt[1:as.numeric(input$Obs),]
})
output$aPlot <- renderPlot({
test <- mydata()
ggplot(data = test, aes(x = test[,1], y = test[,2], group = names(test)[3], color = names(test)[4])) + geom_point()
})
}
shinyApp(ui = ui, server = server)
Change your server to:
server <- function(input, output) {
observe({
dt_plot <- dt[1:input$Obs,]
output$aPlot <- renderPlot({
ggplot(data = dt_plot, aes(x = Col1, y = Col2, group = 'Col3', color = 'Col4')) + geom_point()
})
})
}
My dataset as follows....
fund , sharpe , risk
abc , 1.5 , 7
def , 0 , 5
selectInput("n_breaks", label = "Risk Profile:", choices = c(1,2,3,4,5,6,7,8,9,10), selected = 7)
# Reactive
selectedData <- reactive
a <- mydata %>% filter(risk==as.numeric(input$n_breaks) & sharpe > 0)
renderPlot
ggplot(selectedData(), aes(x = sharpe, y = returns, tooltip = fund, data_id = fund, color=sd)) + geom_point_interactive(size=1)
I am trying to run the below code at renderplot and shiny fails it. Please advise
ggiraph(code = {print(gg_point_3)}, tooltip_offx = 20, tooltip_offy = -10 )
This is an example using the iris dataset.
library(shiny)
library(dplyr)
library(ggplot2)
library(ggiraph)
ui <- shinyUI(fluidPage(
titlePanel("Shiny & ggiraph"),
sidebarLayout(
sidebarPanel(
selectInput("species",
"Select species:",
selected = "setosa",
choices = unique(levels(iris$Species))
)
),
mainPanel(
ggiraphOutput("plotIris")
)
)
))
server <- shinyServer(function(input, output) {
filterIris <- reactive({
filter(iris, Species == input$species)
})
output$plotIris <- renderggiraph({
gg <- ggplot(filterIris(), aes(x = Sepal.Length, y = Petal.Length))
gg <- gg + geom_point_interactive(
aes(tooltip = filterIris()$Sepal.Length), size = 2)
ggiraph(code = print(gg))
})
})
shinyApp(ui = ui, server = server)