5

I am making a shiny app, that shows the user a ggplot after he selects the daterange he is interested in (= the range for the x-axis). So I guess I need to define a reactive data object (correct?).

The ggplot has some subsetting in it. R tells me that reactive data object is not subsettable. In my rookie understanding of ggplot, the subsetting has to be done inside the geom_bar(), geom_line() statements in order to obtain the graph that I want.

  1. Can anyone suggest me how to proceed with the subsetting?
  2. And how to reference the factor category in generating colors for the graph? Thanks!

    sample data

    A = c(3, 4, 3, 5)
    B = c(2, 2, 1, 4)
    Z = c(1, 2, 1, 2)
    R = c(-2, -1, -3, 0)
    S = c(7,7,7,9)
    mydata = data.frame(cbind(A,B,Z,R,S))
    dates = c("2014-01-01","2014-02-01","2014-03-01","2014-04-01")
    mydata$date = as.Date(dates)
    mydata.m = melt(mydata,id="date")
    names(mydata.m) = c("variable", "category","value")
    

    shiny server: select observations as per user input (dateRangeInput)

    data.r = reactive({
      a = subset(mydata.m, variable %in% input$daterange)
      return(a)
    })
    

    shiny server: make the plot

    output$myplot = renderPlot({
    
      # ggplot with proper reference to reactive function <<data.r()>>
      s = ggplot(data.r(), aes(x=variable, fill=category)) +   
    
        # bars for categories A, B, Z: needs subsetting the data... but how?
        + geom_bar(data=subset(data.r(), category %in% c("A","B")), aes(y=value), stat="identity", position="stack")
        + geom_bar(subset=.(category=="Z"), aes(y=-value), stat="identity")
    
        # lines for categories R, S: same.
        + geom_line(subset=.(category=="R"), aes(y=value)) 
        + geom_line(subset=.(category=="S"), aes(y=value))
    
        # how to reference the factor <<category>> in reactive function <<data.r()>>?
        + scale_fill_manual(breaks = levels(category), values = mycolorgenerator(length(levels(category))))
    
      print(s)
    
    })
    

UI.R

# INPUT PART

library(shiny)

shinyUI(pageWithSidebar(
  # Application title
  headerPanel("My App"),

  sidebarPanel( 

    dateRangeInput("daterange", "Date range:",
               start  = "2014-01-01",
               end    = "2014-04-01",
               min    = "2014-01-01",
               max    = "2014-04-01",
               format = "dd/mm/yyyy",
               separator = "-"),

    submitButton(text="Update!")
  ),
# -----------------------------------------------

# OUTPUT PART

  mainPanel(
    tabsetPanel(
      tabPanel("Tab 1", h4("Head 1"),plotOutput("myplot"))
    )
  )
))

SERVER.R

library(reshape)
library(shiny)
library(ggplot2)



# GEN DATA -----------------------------------------------

A = c(3, 4, 3, 5)
B = c(2, 2, 1, 4)
Z = c(1, 2, 1, 2)
R = c(-2, -1, -3, 0)
S = c(7,7,7,9)
mydata = data.frame(cbind(A,B,Z,R,S))
dates = c("2014-01-01","2014-02-01","2014-03-01","2014-04-01")
mydata$date = as.Date(dates)
mydata.m = melt(mydata,id="date")
names(mydata.m) = c("variable", "category","value")







# SERVER -----------------------------------------------
shinyServer(function (input, output) {


# DATA

data.r = reactive({
  a = subset(mydata.m, variable %in% input$daterange)
  return(a)
})



# GGPLOT

mycolorgenerator = colorRampPalette(c('sienna','light grey')) 


output$myplot = renderPlot({

  # ggplot with proper reference to reactive function <<data.r()>>
  s = ggplot(data.r(), aes(x=variable, fill=category))  +  

    # bars for categories A, B, Z: needs subsetting the data... but how?
     geom_bar(data=subset(data.r(), category %in% c("A","B")), aes(y=value), stat="identity", position="stack") +
     geom_bar(subset=.(category=="Z"), aes(y=-value), stat="identity") +

    # lines for categories R, S: same.
     geom_line(subset=.(category=="R"), aes(y=value)) +
     geom_line(subset=.(category=="S"), aes(y=value)) +

    # how to reference the factor <<category>> in reactive function <<data.r()>>?
     scale_fill_manual(breaks = levels(category), values = mycolorgenerator(length(levels(category))))

  print(s)


})
})
user3817704
  • 401
  • 1
  • 5
  • 12
  • 1
    Could you please include your `ui.R` code and the complete `server.R` file for testing this app? – nrussell Jul 22 '14 at 21:29
  • @nrussell: i understand your question, but the real program is quite a bit more complex, and i have spent a good hour to extract from it only what i think is relevant to my question, and turn it into a simple and readable example (but completely nonsense). I would be very greatful for just some suggestion based ff the code directly. By the way you know the ggplot part, you have answered a question about it few days ago :) which is not implemented here, because not relevant for this question (i think). – user3817704 Jul 22 '14 at 21:48
  • 1
    Right, but with `shiny` apps in particular, it's hard to determine what the issue is without being able to run the app. – nrussell Jul 22 '14 at 21:52
  • ok, i will do asap (=tomorrow). thanks already. – user3817704 Jul 22 '14 at 21:53
  • Where is the `.()` function supposed to come from. Did you miss a library? – MrFlick Jul 22 '14 at 22:28
  • MrFlick, thanks! So simple. For the .() and subset parameter, saw it somewhere when researching for the plot, and it works fine outside shiny, no library needed to my knowledge (see my question 'geom_bar stacked dodged'. But i start to see now that it is not proper code, thanks for pointing out. Regards – user3817704 Jul 23 '14 at 06:44
  • @About the .() function: I am using it also in ddply() function for clean positioning of value labels in ggplot stacked barcharts (again based on someone else's brilliance). Would love to know what exactly it does, but for now it just gives me clean results... Ex: library(plyr); df = ddply(df, .(col1, col2), mutate, csum = cumsum(col3)-col3/2); ggplot(yourdata) + geom_text(aes(y = csum, label =paste(col3)); – user3817704 Jul 23 '14 at 18:01

1 Answers1

7

(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

MrFlick
  • 195,160
  • 17
  • 277
  • 295