Reputation: 1473
When I create a tiny dataframe and run both a direct plot to the PLOT tab in RStudio, followed by an attempt to run the same concept in Shiny, the direct plot works and the Shiny plot comes out blank with the error message:
Warning in xy.coords(x, y, xlabel, ylabel, log) :
NAs introduced by coercion
What am I doing wrong?
I based this code attempt on reading on the web and a prior answer here in Stack Overflow so it's close, but I'm missing some implicit conversion or something. I just want to use Shiny to plot two columns of a data frame.
library(shiny)
dfx <- data.frame(xx=c(1,2,3,4,5),
yy=c(2,4,6,8,10))
plot(dfx$xx, dfx$yy, xlim=c(0,6), ylim=c(0,10))
# the result in PLOTS in RStudio is a 5 point rising line graph as expected.
ui <- fluidPage(
headerPanel('my first shiny app'),
sidebarPanel(
selectInput('xcol', 'X Variable', names(dfx)),
selectInput('ycol', 'Y Variable', names(dfx))
),
mainPanel(
plotOutput('plot1')
)
)
server <- function(input, output) {
output$plot1 <- renderPlot({
plot(input$xcol, input$ycol, xlim=c(0,6), ylim=c(0,10))
})
}
shinyApp(ui = ui, server = server)
# the result of this in shiny is a blank graph
Upvotes: 3
Views: 360
Reputation: 1473
So aside from the double square brackets notation solution mentioned above, which works, and explained here davetang.org/muse/2013/08/16/double-square-brackets-in-r –
I want to document that there is also a solution using "reactive", such as the following, where the "reactive" function dynamically looks up the value described by the column name text field, and then (don't forget!) the "variables" so defined (Xvalues, Yvalues) are treated as if they are functions (which they end up being) so the syntax requires putting "()" after them when using them.. The following works:
library(shiny)
df <- data.frame(xx=c(1,2,3,4,5),
yy=c(2,4,6,4,2))
# the result in PLOTS in RStudio is a 5 point rising line graph as expected.
ui <- fluidPage(
headerPanel('my first shiny app'),
sidebarPanel(
selectInput('xcol', 'X Variable', names(df)),
selectInput('ycol', 'Y Variable', names(df))
),
mainPanel(
plotOutput('plot1')
)
)
server <- function(input, output) {
Xvalues <- reactive({ df[,input$xcol] })
Yvalues <- reactive({ df[,input$ycol] })
output$plot1 <- renderPlot({
plot(Xvalues(), Yvalues(), xlim=c(0,6), ylim=c(0,10))
})
}
shinyApp(ui = ui, server = server)
One example I found is explained for newbies here
which states:
Reactive contexts
Reactive values are special constructs in Shiny; they are not seen anywhere else in R programming. As such, they cannot be used in just any R code, reactive values can only be accessed within a reactive context.
This is the reason why any variable that depends on a reactive value must be created using the reactive() function, otherwise you will get an error. The shiny server itself is not a reactive context, but the reactive() function, the observe() function, and all render*() functions are.
An example provided in the "Shiny from RStudio" tutorial at https://shiny.rstudio.com/tutorial/ In the downloadable content's first case, in the file "app.R" they used "reactive" this way but I didn't understand what it was doing, which is slightly obscured by using reactive to process TWO data column vectors at once! This runs.
# 01-kmeans-app
palette(c("#E41A1C", "#377EB8", "#4DAF4A", "#984EA3",
"#FF7F00", "#FFFF33", "#A65628", "#F781BF", "#999999"))
library(shiny)
ui <- fluidPage(
headerPanel('Iris k-means clustering'),
sidebarPanel(
selectInput('xcol', 'X Variable', names(iris)),
selectInput('ycol', 'Y Variable', names(iris),
selected = names(iris)[[2]]),
numericInput('clusters', 'Cluster count', 3,
min = 1, max = 9)
),
mainPanel(
plotOutput('plot1')
)
)
server <- function(input, output) {
selectedData <- reactive({
iris[, c(input$xcol, input$ycol)]
})
clusters <- reactive({
kmeans(selectedData(), input$clusters)
})
output$plot1 <- renderPlot({
par(mar = c(5.1, 4.1, 0, 1))
plot(selectedData(),
col = clusters()$cluster,
pch = 20, cex = 3)
points(clusters()$centers, pch = 4, cex = 4, lwd = 4)
})
}
shinyApp(ui = ui, server = server)
Upvotes: 0
Reputation: 206506
In shiny, input$xcol
is just a string that's returned from the UI. So if you use those values, it's like calling
plot("xx", "yy", xlim=c(0,6), ylim=c(0,10))
which returns the same error you get in Shiny.
If you want to get the values from your data.frame, you need to do dfx[[input$xcol]]
. So try
plot(dfx[[input$xcol]], dfx[[input$ycol]], xlim=c(0,6), ylim=c(0,10))
Of course plot()
is the base R plotting command. If you did want to use ggplot
, you'd use something like
ggplot(dfx) +
aes(.data[[input$xcol]], .data[[input$ycol]]) +
geom_point()
Upvotes: 5