Shiny + ggplot: How to subset reactive data object?
(The complete server.R and ui.R really helped)
I'm not sure where you got the .()
function from or the idea that geom_bar
has a subset=
parameter. But here's an updated renderPlot
that doesn't seem to generate any errors at least
output$myplot = renderPlot({
dd<-data.r()
# ggplot with proper reference to reactive function <<data.r()>>
s = ggplot(dd, aes(x=variable, fill=category)) +
# bars for categories A, B, Z: needs subsetting the data... but how?
geom_bar(data=subset(dd, category %in% c("A","B")), aes(y=value),
stat="identity", position="stack") +
geom_bar(data=subset(dd, category=="Z"), aes(y=-value), stat="identity") +
# lines for categories R, S: same.
geom_line(data=subset(dd, category=="R"), aes(y=value)) +
geom_line(data=subset(dd, category=="S"), aes(y=value)) +
scale_fill_manual(breaks = levels(dd$category),
values = mycolorgenerator(length(levels(dd$category))))
print(s)
})
Mostly I changed the data=
to explicit subset()
calls
Subset a reactive dataframe in R
There are two ways of solving this:
- Store dataframes inside
reactiveValues
objects (see: Creating a reactive dataframe with shiny apps for quite similar issue) - Coerce reactive expression to regular R variable via
rt.df <- rt()
before callingcor
or other functions that don't handle reactives gracefuly.
R, shiny: reactive data.frame as a factor, set levels and order
When you use:
dataforplot <- reactive({
plot_data <- data() %>%
filter(Name %in% input$polymers)
plot_data$ID_Polymer <- factor(plot_data$ID_Polymer,
levels =plot_data$ID_Polymer[ order(plot_data[["Content"]])])
})
The last line of whatever is inside your reactive()
is returned as the value of that reactive element. Hence, in your case plot_data$ID_Polymer
(which is not a dataframe, but a factor column of the dataframe) is returned as dataforplot()
. This is the reason for the error. Change you dataforplot()
definition to:
dataforplot <- reactive({
plot_data <- data() %>%
filter(Name %in% input$polymers)
plot_data$ID_Polymer <- factor(plot_data$ID_Polymer,
levels =plot_data$ID_Polymer[ order(plot_data[["Content"]])])
# Add return statement for returning the dataframe
return(plot_data)
})
How to create a shiny reactive function with input in a separate R
You could pass input
as argument to the reactive function:
newdate <- function(input) {
reactive({
req(input$range)
df %>% filter(between(date, input$range[1], input$range[2]))
})
}
The call to the function in the server is then:
plot <- newdate(input)() %>% ...
R Shiny ggplot reactive to varSelectInput
Welcome to stackoverlfow.
There are a few things you have to change in order to have a functional app. I put here a summary of the things I saw, and details within the code as comments.
- Prepare your data, you should consider creating variables
- Do not put a whole vector with duplicated values as
choices
argument in aselectInput
, you should pass the distinct options. - It is a good idea to select a value whenever is possible. that way your app will launch with something to show as default.
- Use the inputs to filter the data.
selectInput
create a string value, there for, your should useaes_string
in your ggplotmapping
argument.
library(shiny)
library(tidyverse)
# You have to Adequate your data: You have to create a dete variable
# in order to make the `dateRangeInput` work. You can do that using
# `year`, `month` and `day` variables as follow.
flights <- nycflights13::flights %>%
mutate(
date = as.Date(paste(year, month, day, sep = "-"))
)
ui <- navbarPage(
title = "NYC Flights",
tabPanel(
title = "Flights",
sidebarPanel(
h4("Flight Inputs"),
# The choices argument should be the unique
# list of arilines, not the whole vector with
# duplicates
selectInput(
"airline",
label = "Select Airline",
choices = unique(flights$carrier),
selected = 'UA' # It is a good idea to select a value
# visible when you launch the app
),
dateRangeInput(
"dates",
label = "Dates",
start = min(flights$date),
end = max(flights$date)
),
varSelectInput(
"X_Axis",
label = "Select Variable 1",
data = flights,
selected = "date" # selecting one
),
varSelectInput(
"Y_Axis",
label = "Select Variable 2",
data = flights,
selected = "dep_delay" # selecting one
)
),
mainPanel(
plotOutput("plot")
)
)
)
server <- function(input, output, session) {
output$plot <- renderPlot({
flights %>%
# Use your inputs to filter the data
filter(date >= input$dates[1], date <= input$dates[2], carrier == input$airline) %>%
# since the selectImput create a character element, you should use
# ase_string() to map the x an y variables
ggplot(aes_string(x = input$X_Axis, y = input$Y_Axis)) +
geom_point()
})
}
shinyApp(ui, server)
Related Topics
R: How to Select Files in Directory Which Satisfy Conditions Both on the Beginning and End of Name
Adding Regression Line Equation and R2 on Separate Lines Graph
Different Results with Randomforest() and Caret's Randomforest (Method = "Rf")
Faster Way to Compare Rows in a Data Frame
How Can a Script Find Itself in R Running from the Command Line
How to Read Knitr/Rmd Cache in Interactive Session
R Data.Table: Subgroup Weighted Percent of Group
R Lubridate Converting Seconds to Date
How to Flip Rows and Columns in R
Import Multiple Text Files in R and Assign Them Names from a Predetermined List
How Do Add a Column in a Data Frame in R
Using Filtered Datatables in Shiny
Ggplot2: How to Adjust Fill Colour in a Boxplot (And Change Legend Text)
Apply Tidyr::Separate Over Multiple Columns
Warning When Defining Factor: Duplicated Levels in Factors Are Deprecated