5

I want to make a simple sales report line chart that shows product sales over time for a given product from a drop down menu. I have made a report using plotly and shiny, but I can't find a way to share the report with my colleagues, without having to use Shiny Server or Shinyapps.IO. Ideally, I would want a standalone html file, but I can't find a way to insert an interactive graph to R Markdown.

Here is an example dataframe:

df = data.frame(month=rep_len(1:12, length.out=12*5), product=rep(1:5, each=12),sales=rnorm(12*5,100,50)) 
alan ocallaghan
  • 3,116
  • 17
  • 37
Ullsokk
  • 697
  • 2
  • 11
  • 24
  • How many products do you have? You could consider some tabs like https://stackoverflow.com/questions/38062706/rmarkdown-tabbed-and-untabbed-headings – MrGumble Jan 04 '18 at 13:53
  • ggvis? https://ggvis.rstudio.com/interactivity.html – MLavoie Jan 04 '18 at 16:22

2 Answers2

8

The following example accomplishes exactly what you want and can be embedded in RMarkdown, then converted to a standalone HTML page that can be viewed offline or hosted on a server:

## Create random data. cols holds the parameter that should be switched
l <- lapply(1:100, function(i) rnorm(100))
df <- as.data.frame(l)
cols <- paste0(letters, 1:100)
colnames(df) <- cols
df[["c"]] <- 1:100

## Add trace directly here, since plotly adds a blank trace otherwise
p <- plot_ly(df,
      type = "scatter",
      mode = "lines",
      x = ~c, 
      y= ~df[[cols[[1]]]], 
      name = cols[[1]])
## Add arbitrary number of traces
## Ignore first col as it has already been added
for (col in cols[-1]) {
  p <- p %>% add_lines(x = ~c, y = df[[col]], name = col, visible = FALSE)
}

p <- p %>%
    layout(
      title = "Dropdown line plot",
      xaxis = list(title = "x"),
      yaxis = list(title = "y"),
      updatemenus = list(
        list(
            y = 0.7,
            ## Add all buttons at once
            buttons = lapply(cols, function(col) {
              list(method="restyle", 
                args = list("visible", cols == col),
                label = col)
            })
        )
      )
    )

print(p)
alan ocallaghan
  • 3,116
  • 17
  • 37
  • Thank you! This gets me one step closer at least. But does this approach require a hard coding of each group? I have several hundred groups, is there a way to make this work in a dataframe that is formatted with a group and a value column, instead of one column for each group of values? e.g. a product name and sales number column. – Ullsokk Jan 05 '18 at 09:00
  • See updated answer for a general solution. I assume that you mean "tidy" type data? This won't work with that, so it would probably be easier to use `reshape2` to make the data "wide" before plotting – alan ocallaghan Jan 05 '18 at 12:07
  • On second viewing, there seems to be a bug. The column in the dropdown doesnt correspond to the correct line showing up in the chart – Ullsokk Jan 08 '18 at 08:49
  • b2 shows both the line for a1 and v100, while c3 onwards shows the line for column x minus 2, so c3 shows a1, d4 shows b2 etc. – Ullsokk Jan 08 '18 at 09:23
  • This is now fixed – alan ocallaghan Jan 09 '18 at 18:14
  • Excellent! thank you so much. I was trying to find the error yesterday, but I was nowhere near the sullotion. – Ullsokk Jan 10 '18 at 08:17
  • Cheers! Might be worth removing the section of the question which mentions my answer, to avoid confusion – alan ocallaghan Jan 10 '18 at 19:17
2

No, that's sort of the point of Shiny - that you have a live session with an R server. If you want to get the result completely in an html file, you'd probably want to pre-make all the charts and then display the results from a markdown file. I believe you can use drop-down menus in markdown with the bsselectR package.

  • I am playing around with https://plot.ly/r/dropdowns/ but I can't quite understand if the dropdown can be used to filter a data set or to just modify the plots. Will check out bsselectR – Ullsokk Jan 04 '18 at 14:47