boshek
boshek

Reputation: 4416

Using lead/lag in a Shiny App

I feel like this question applies to a general query about how to manipulate data within a Shiny context but my specific question relates to the usage of the lead/lag functions in dplyr. Right now I am faced with two problems.

The first problem is defining the variables in the dataset that have been lead/lag. I am using a dplyr approach where I name the lagged variable yvar. CLearly this isn't correct as R isn't able to find yvar. So can anyone recommend a way to change/create a variable so that the result is transferred down through the shiny app and available to be called?

The second problem is specifying the number of rows to lead/lag the Y variable. It is easy enough in the ui.R file to specify an input box with lead/lag positions. But then how do I place the integer from that input box as an argument in the lead function?

Here is the ui.R:

library(shiny)
library(ggplot2)
library(dplyr)


dataset <- iris

shinyUI(pageWithSidebar(

  headerPanel("Iris Data Explorer"),

  sidebarPanel(


    selectInput('x', 'X', names(dataset), names(dataset)[[2]]),
    selectInput('y', 'Y', names(dataset), names(dataset)[[4]]),
    selectInput('offset', 'Offset Level of Y', 0:5, 0),
    selectInput('species', 'Species', levels(dataset$Species), "virginica")
  ),

  mainPanel(
    plotOutput('plot')
  )
))

And here is the server.R:

library(shiny)
library(ggplot2)
library(dplyr)


shinyServer(function(input, output) {

  dataset <- reactive({
    iris %>%
      filter(Species==input$species) 
    #%>% mutate(yvar=lead(input$y, paste0(input$offset)))
  })



  output$plot <- renderPlot({


    dataset<-dataset()
    p <- ggplot(dataset, aes_string(x=input$x,
                                    #y=yvar)
                                    y=input$y
    )) +
      geom_point() 

    print(p)

  }, height=500)

})

Upvotes: 1

Views: 368

Answers (1)

Mike Wise
Mike Wise

Reputation: 22827

I think this is what you want. To get it to work I did the following:

  • abandoned mutate because it apparently is quite difficult to use dynamic names with it (see:R - dplyr - mutate - use dynamic variable names) and just did it with data frame indexing as suggested there.
  • combined it into one file so I can see everything at once (good for small stuff)
  • added a print statement to dump the dataset on every change so you can see what is happening.
  • added quotes to the yvar variable so that it works with aesstring
  • added an as.numeric to the offset variable as an input to lead

This is the resulting code:

library(shiny)
library(ggplot2)
library(dplyr)

dataset <- iris

u <- shinyUI(pageWithSidebar(
  headerPanel("Iris Data Explorer"),
  sidebarPanel(
    selectInput('x', 'X', names(dataset), names(dataset)[[2]]),
    selectInput('y', 'Y', names(dataset), names(dataset)[[4]]),
    selectInput('offset', 'Offset Level of Y', 0:5, 0),
    selectInput('species', 'Species', levels(dataset$Species), "virginica")
  ),
  mainPanel(
    plotOutput('plot')
  )
))
s <- shinyServer(function(input, output) {
  dataset <- reactive({
    df <- iris %>% filter(Species==input$species) 
    df[["yvar"]] <- lead(df[[input$y]],as.numeric(input$offset))
    return(df)
  })
  output$plot <- renderPlot({
    dataset<-dataset()
    print(dataset)
    ggplot(dataset, aes_string(x=input$x,y="yvar")) + geom_point(na.rm=T) 
  }, height=500)
})
shinyApp(ui=u,server=s)

And this is what it looks like: enter image description here

Upvotes: 3

Related Questions