8

I've found an interesting package rpivotTable. I'd like to create shiny app which includes rpivotTable with the possibility to download generated data using downloadHandler.

However, I am unable to find the solution, how to create data.frame or something else which I'd be able to pass to the downloadHandler function.

rpivotTable creates an object of class:

class(pivot)
[1] "rpivotTable" "htmlwidget" 

Is threne any possibilities to download the output of the this function?

Also, I enclose the example, how the pivot is created in shiny and the example of download function which I'd like to use.

Maybe are the any other ideas or suggestions?

set.seed(1992)
n=99
Year <- sample(2013:2015, n, replace = TRUE, prob = NULL)
Month <- sample(1:12, n, replace = TRUE, prob = NULL)
Category <- sample(c("Car", "Bus", "Bike"), n, replace = TRUE, prob = NULL)
Brand <- sample("Brand", n, replace = TRUE, prob = NULL)
Brand <- paste0(Brand, sample(1:14, n, replace = TRUE, prob = NULL))
USD <- abs(rnorm(n))*100

df <- data.frame(Year, Month, Category, Brand, USD)



output$Pivot <- rpivotTable::renderRpivotTable({
 rpivotTable(data = df, rows = "Brand", col = "Category", vals = "USD", aggregatorName = "Sum", rendererName = "Table")
})



  output$downloadData <- downloadHandler(
   filename = function() { paste(filename, '.csv', sep='') },
   content = function(file) {
   write.csv(PivotOutput, file)
})
Cœur
  • 37,241
  • 25
  • 195
  • 267
AK47
  • 1,318
  • 4
  • 17
  • 30
  • 1
    I'm the author of the package. I'm a bit confused by what you are trying to achieve. rpivotTable does not generate any data: it simply slice and dice the data provided. In your example the data to be downloaded would be `df`. Or am I missing something? – Enzo Oct 24 '15 at 09:58
  • Hi, thanks for the response! – AK47 Oct 24 '15 at 14:28
  • Hi, thanks for the response! What I'd like to do is to save those slices made with rpivotTable in data frame. For example i have Year in rows, Brand in column and the USD as a value. Is there a way to store this slice in a data frame or something like that? My aim is to export data which is sliced with the pivot – AK47 Oct 24 '15 at 14:36
  • This is not possible. Theoretically there could be a way. Nicolas has an example where the slice and dice parameters are sent back. I haven't implemented this feature (I need js help!), but imagine if you could get back into R the latest parameters used to see the data, you could use them to filter the data.frame and save. – Enzo Oct 24 '15 at 20:04
  • May I see this example? It would help me a lot! – AK47 Oct 26 '15 at 13:10
  • 2
    I've just got some code and I will post this function and an example on github. Give me a couple of hours. – Enzo Oct 26 '15 at 13:59

3 Answers3

5

I've just pushed on the master branch of rpivotTable on github a change that addresses the issue of getting the parameters the user is / has looked at on the server side.

Download the rpivotTable code with devtools:

devtools::install_github("smartinsightsfromdata/rpivotTable",ref="master")

This is an example of how to get the selected data on the server side. The example is not complete for your needs: you need to subset the original data frame with what you get back from rpivotTable. But this should be enough to give you an head start.

library(rpivotTable)
library(shiny)

list_to_string <- function(obj, listname) {
  if (is.null(names(obj))) {
    paste(listname, "[[", seq_along(obj), "]] = ", obj,
          sep = "", collapse = "\n")
  } else {
    paste(listname, "$", names(obj), " = ", obj,
          sep = "", collapse = "\n")
  }
}

server <- function(input, output) {

output$pivotRefresh <- renderText({

cnames <- list("cols","rows","vals", "exclusions","aggregatorName", "rendererName")
# Apply a function to all keys, to get corresponding values
allvalues <- lapply(cnames, function(name) {
  item <- input$myPivotData[[name]]
  if (is.list(item)) {
    list_to_string(item, name)
  } else {
    paste(name, item, sep=" = ")
  }
})
paste(allvalues, collapse = "\n")
})

output$mypivot = renderRpivotTable({
    rpivotTable(data=cars, onRefresh=htmlwidgets::JS("function(config) { Shiny.onInputChange('myPivotData', config); }"))
  })
}

ui <- shinyUI(fluidPage(
  fluidRow(column(6,   verbatimTextOutput("pivotRefresh")),
           column(6, rpivotTableOutput("mypivot") ))
)
)

shinyApp(ui = ui, server = server) 
Enzo
  • 2,543
  • 1
  • 25
  • 38
  • I might have a go at a pivottable json export in the next couple of weeks. Will let you know. – timelyportfolio Oct 27 '15 at 11:55
  • @timelyportfolio the actual output from onRefresh is a list(of lists) with the parameters, so the json conversion shouldn't be an issue. On the other hand I wonder what would be the benefit of a json export for the OP. The missing piece to download the data as csv is a function that has as entry point: the data frame, the parameters from onRefresh, and in output the subsetted data frame to be saved as csv. – Enzo Oct 27 '15 at 13:00
  • Did you find any solution for downloading rPivotTable? – user3463225 Nov 18 '16 at 13:38
2

To extend Enzo's excellent answer (Thank you for the awesome package), I mocked up the following as a way to get the summarized data and use it inside shiny.

This uses the onRefresh to watch for changes in the config, then uses the DOM to get the innerHTML of the relevant element. In this case, then uses rvest to clean that html and extract the table, and finally, for demo purposes, shows it inside a DT::datatable.

This might be too hacky, but it can be straightforwardly downloaded as a CSV then, or passed to other shiny elements for further processing.

ui.R

library(shiny)
library(DT)
library(rpivotTable)

FullPage <- fluidPage(
    DT::dataTableOutput('aSummaryTable'),
    rpivotTableOutput('RESULTS')
)

FullPage

server.R:

library(shiny)
library(rpivotTable)
library(DT)
library(rvest)

function(input, output, session) {

  # Make some sample data
  qbdata <- reactive({
    expand.grid(LETTERS,1:3)
  })

  # Clean the html and store as reactive
  summarydf <- eventReactive(input$myData,{
    input$myData %>% 
       read_html %>% 
       html_table(fill = TRUE) %>% 
       # Turns out there are two tables in an rpivotTable, we want the second
       .[[2]]

  })

  # show df as DT::datatable
  output$aSummaryTable <- DT::renderDataTable({
      datatable(summarydf(), rownames = FALSE)
  })

  # Whenever the config is refreshed, call back with the content of the table
  output$RESULTS <- renderRpivotTable({
    rpivotTable(
      qbdata(),
      onRefresh = 
        htmlwidgets::JS("function(config) { 
                           Shiny.onInputChange('myData', document.getElementById('RESULTS').innerHTML); 
                        }")
    )
  })

}
Shape
  • 2,892
  • 19
  • 31
0

A the github repository rpivotTabletocsv I try to implement the export of rpivotTable to csv from a download button from Rshiny App.

Omar Giorgetti
  • 137
  • 1
  • 6