I don't understand why my R code give me this error:
data must be a data frame, or other object coercible by fortify(), not a numeric vector.
library(shiny)
library(ggplot2)
ui <- fluidPage( sliderInput(inputId = "num",
label = "Choose a number",
value = 25, min = 1, max = 100), plotOutput("ggplot") )
server <- function(input, output) { output$ggplot <- renderPlot({
ggplot(data=rnorm(input$num), aes(input$num)) + geom_histogram() }) }
shinyApp(ui = ui, server = server)
The first argument to ggplot should be a data frame. You have supplied the output of rnorm(), which is a vector. That's the first problem.
The second is that aes() should refer to a column name in the supplied data frame.
I would create a data frame first using input$num. Something like this:
server <- function(input, output) {
data_df <- data.frame(x = rnorm(as.numeric(input$num)))
output$ggplot <- renderPlot({
ggplot(data = data_df, aes(x = x)) + geom_histogram()
})
}
Related
I want to control the xlim using numericrangeInput. Initial values are set as c(NA,NA).
If I try to change the scale min and max values and before updating one of the values it throws error Missing values cannot be used where TRUE/FALSE values are required
Any suggestions to fix this error.
Below is the code
library(shiny)
library(tidyverse)
data <- faithful %>% mutate(eruptionTime=lubridate::now() + lubridate::dhours(cumsum(waiting)))
ui <- fluidPage(
numericRangeInput(inputId = "noui1", label = "Numeric Range Input:",
value = c(NA, NA)
),
plotOutput("plot9")
)
server <- function(input, output) {
output$plot9 <- renderPlot({
print(paste("What is the condition",!anyNA(input$noui1)))
iris %>%ggplot() + geom_point(aes(x=Sepal.Length, y=Petal.Length)) +
coord_cartesian(xlim=input$noui1)
})
}
shinyApp(ui = ui, server = server)
You can update the plot only after you input both the numbers in numericRangeInput.
Try this code -
library(shiny)
library(tidyverse)
data <- faithful %>% mutate(eruptionTime=lubridate::now() + lubridate::dhours(cumsum(waiting)))
ui <- fluidPage(
numericRangeInput(inputId = "noui1", label = "Numeric Range Input:",
value = c(NA, NA)
),
plotOutput("plot9")
)
server <- function(input, output) {
output$plot9 <- renderPlot({
plot <- iris %>%ggplot() + geom_point(aes(x=Sepal.Length, y=Petal.Length))
if(length(input$noui1) == 2)
plot <- plot + coord_cartesian(xlim=input$noui1)
plot
})
}
shinyApp(ui = ui, server = server)
I am relatively new to R, and I'm trying to build a reactive ggplot in Shiny where the X-axis (dates) is reactive to a dateRangeInput in the UI. I've been googling everywhere, but every thing I try returns an error.
In the ggplot, the aes() calls from a dataset called datecorrected_totals, where x is the dates, and y=load are the two values that I would like to be reactive to the dateRangeInput so the ggplot will adjust the scale based on the period within the daterangeinput.
library(tidyverse)
library(shiny)
library(tidyr)
library(lubridate)
library(zoo)
data <- read_csv("--")
# Define UI ----
ui <- fluidPage(
titlePanel("--"),
sidebarLayout(
sidebarPanel(
h3("Calculator"),
dateRangeInput("dates", label = "Dates",
start = ("10-18-2018"),
end = max("05-29-2019"),
min = min("10-18-2018"),
max = max("05-29-2019"),
format = "mm-dd-yyyy"),
sliderInput("slider_a", label = "--",
min = 0,
max = 7,
value = 0),
sliderInput("slider_c", label = "--",
min = 7,
max = 42,
value = 7)
),
mainPanel(plotOutput('bar_chart'))
)
)
# Define server logic ----
server <- function(input, output, session) {
RE <- reactive({
})
output$bar_chart <- renderPlot(
ggplot(data = datecorrected_totals, aes(x = x, y = load)) +
geom_bar(stat = "identity")
)
}
# Run the app ----
shinyApp(ui = ui, server = server)
You need to filter the original dataset by the input dates. In this example data would be your original dataset.
RE <- reactive({
data %>%
filter(x>=input$dates[1] & x<=input$dates[2])
})
output$bar_chart <- renderPlot(
ggplot(data = RE(), aes(x = x, y = load)) +
geom_bar(stat = "identity")
There is no need to create a separate reactive() expression (unless required otherwise). The filter can be applied directly in renderPlot(). Thus, output$bar_chart becomes
output$bar_chart <- renderPlot(
datecorrected_totals %>%
filter(between(x, input$dates[1], input$dates[2])) %>%
ggplot(aes(x = x, y = load)) +
geom_bar(stat = "identity")
)
Below is a self-contained minimal reproducible example:
library(tidyverse)
library(lubridate)
library(shiny)
datecorrected_totals <- tibble(x = seq(as.Date("2018-10-18"), as.Date("2019-05-29"), length.out = 10L),
load = day(x))
# Define UI ----
ui <- fluidPage(
titlePanel("--"),
sidebarLayout(
sidebarPanel(
h3("Calculator"),
dateRangeInput("dates", label = "Dates",
start = mdy("10-18-2018"),
end = mdy("05-29-2019"),
min = mdy("10-18-2018"),
max = mdy("05-29-2019"),
format = "mm-dd-yyyy"),
),
mainPanel(plotOutput('bar_chart'))
)
)
# Define server logic ----
server <- function(input, output, session) {
output$bar_chart <- renderPlot(
datecorrected_totals %>%
filter(between(x, input$dates[1], input$dates[2])) %>%
ggplot(aes(x = x, y = load)) +
geom_col()
)
}
# Run the app ----
shinyApp(ui = ui, server = server)
Note that the date strings have been coerced to valid Date objects by calling mdy() to avoid error messages.
In addition, geom_bar(stat = "identity") has been replaced by geom_col().
I would like two plots to appear. First, a scatter plot and then a line graph. The graphs aren't important. This is my first time using Shiny. What is the best way to have both
plotOutput("needles"),
plotOutput("plot")
use the data from the same needles data frame? I think I'm getting confused as to how to pass the "needles" data frame between the plotOutput functions.
library(shiny)
library(tidyverse)
library(scales)
# Create the data frame ________________________________________________
create_data <- function(num_drops) {
needles <- tibble (
x = runif(num_drops, min = 0, max = 10),
y = runif(num_drops, min = 0, max = 10)
)
}
# Show needles ________________________________________________
show_needles <- function(needles) {
ggplot(data = needles, aes(x = x, y = y)) +
geom_point()
}
# Show plot __________________________________________________
show_plot <- function(needles) {
ggplot(data = needles, aes(x = x, y = y)) +
geom_line()
}
# Create UI
ui <- fluidPage(
sliderInput(inputId = "num_drops",
label = "Number of needle drops:",
value = 2, min = 2, max = 10, step = 1),
plotOutput("needles"),
plotOutput("plot")
)
server <- function(input, output) {
output$needles <- renderPlot({
needles <- create_data(input$num_drops)
show_needles(needles)
})
output$plot <- renderPlot({
show_plot(needles)
})
}
shinyApp(ui = ui, server = server)
We could execute the create_data inside a reactive call in the server and then within the renderPlot, pass the value (needles()) as arguments for show_needles and show_plot
server <- function(input, output) {
needles <- reactive({
create_data(input$num_drops)
})
output$needles <- renderPlot({
show_needles(needles())
})
output$plot <- renderPlot({
show_plot(needles())
})
}
shinyApp(ui = ui, server = server)
-output
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()
})
})
}
I have a server.R file in the following form:
server.R
shinyServer(
function(input, output, session) {
mydata<- reactive({
df<- dataframe1
variable1
variable2
list(df, variable1, variable2)
})
output$plot<- renderPlot({
p<-ggplot(mydata()$df, aes(y=V8, x = 1:nrow(mydata()$df), fill = V8))
print(p)
})
})
My issue is that the call to ggplot, while it seems to recognize mydata$df(), it returns the error
Error in nrow(mydata()$df) : could not find function "mydata".
I am not sure where my syntax is wrong. Can anyone shed some light? Thanks!
To my knowledge, reactive shiny objects don't play well with lists. As it appears you aren't using 'variable1' and 'variable2' just omit them and just do the dataframe (which I assume has been made globally accessible and isn't imported?). It also could simply be calling the reactive before the ggplot call, but I err towards simplicity if not using those extra variables. A very quick example:
runApp(
list(ui = basicPage(
h1('Demo Shiny'),
plotOutput("plot")
)
,server = function(input, output) {
mydata <- reactive({
dataframe1 <- data.frame(cond = rep(c("A", "B"), each=10),
xvar = 1:20 + rnorm(20,sd=3),
yvar = 1:20 + rnorm(20,sd=3))
dataframe1
})
output$plot = renderPlot({
df <- mydata()
p<-ggplot(df, aes(x=xvar, y = yvar)) + geom_point()
print(p)
})
})
)
I'm going to shamless steal most of #charles code, but i think the problem in this case is actually your aes(). This seems to work
runApp(
list(ui = basicPage(
h1('Demo Shiny'),
plotOutput("plot")
)
,server = function(input, output) {
mydata <- reactive({
df <- data.frame( V8=sample(1:4, 20, replace=T))
list(df=df, variable1=1, variable2=2)
})
output$plot = renderPlot({
p<-ggplot(mydata()$df, aes(x=seq_along(V8), y = V8)) + geom_point()
print(p)
})
})
)
The problem was referring to variables in your aes that were not in your data.frame that you passed to ggplot2. Here by making sure to include a proper variable from the df, we seem to be fine.