闪亮的DataTables页脚回调总和

时间:2017-03-14 21:24:20

标签: r datatables shiny dt

我正致力于在callback应用DataTables应用中为shiny应用DataTables实施DT功能。到目前为止,我对阅读sum this example(第4.4节)的想法是,可以通过columnDefs options参数应用相同的类columnDefs如下所示,但如果我只知道在哪里放置JS参数来手动完成类链接也是有意义的。

您可以删除所有callbacklibrary(shiny) library(DT) ui <- fluidPage( title = 'Select Table Rows', hr(), h1('A Server-side Table'), fluidRow( column(9, DT::dataTableOutput('x3')) ) ) server <- function(input, output, session) { # server-side processing mtcars2 = mtcars[, 1:8] output$x3 = DT::renderDataTable(DT::datatable(mtcars2, extensions = 'Buttons', options = list( scrollX = TRUE, scrollY = TRUE, pageLength = 10, order = list(list(1, 'asc')), fixedHeader = TRUE, dom = 'Blrtip', buttons = c('copy', 'csv', 'excel', 'pdf', 'print') # columnDefs = JS("[ # { className: 'sum', 'targets': [ 1,2 ] } # ]") # ), #callback = JS( # " function(row, data, start, end, display) { # var api = this.api(); # # api.columns('.sum', { page: 'current' }).every(function () { # var sum = api # .cells( null, this.index(), { page: 'current'} ) # .render('display') # .reduce(function (a, b) { # var x = parseFloat(a) || 0; # var y = parseFloat(b) || 0; # return x + y; # }, 0); # console.log(this.index() +' '+ sum); //alert(sum); # $(this.footer()).html(sum); # }); #}" ) ) ) } shinyApp(ui = ui, server = server) 参数,以查看示例起点。

app.R

library(shiny)
library(DT)

ui <- fluidPage(

  title = 'Select Table Rows',

  hr(),

  h1('A Server-side Table'),

  fluidRow(
    column(9, DT::dataTableOutput('x3'))
  )

)


server <- function(input, output, session) {

  # server-side processing

  mtcars2 = mtcars[, 1:8]

  sketch <- htmltools::withTags(table(
                  class = "display",
                  style = "bootstrap",
                  tableHeader(colnames(mtcars2)),
                  tableFooter(colnames(mtcars2))
          ))

  output$x3 = DT::renderDataTable(DT::datatable(mtcars2,
                                                container = sketch,
                                                extensions = 'Buttons',
                                                options = list(
                                                  scrollX = TRUE,
                                                  scrollY = TRUE,
                                                  pageLength = 10,
                                                  order = list(list(1, 'asc')),
                                                  dom = 'Blrtip',
                                                  buttons = c('copy', 'csv', 'excel', 'pdf', 'print'),
                                                  footerCallback = JS(
       "function( tfoot, data, start, end, display ) {",
       "var api = this.api(), data;",
        "total = api.column( 1, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
        "total1 = api.column( 2, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
       "total2 = api.column( 3, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
        "total3 = api.column( 4, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
       "total4 = api.column( 5, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
        "total5 = api.column( 6, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
       "total6 = api.column( 7, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
        "total7 = api.column( 8, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )",
        "$( api.column( 1 ).footer() ).html(total.toFixed(2));
        $( api.column( 2 ).footer() ).html(total1.toFixed(2));
        $( api.column( 3 ).footer() ).html(total2.toFixed(2));
        $( api.column( 4 ).footer() ).html(total3.toFixed(2));
        $( api.column( 5 ).footer() ).html(total4.toFixed(2));
        $( api.column( 6 ).footer() ).html(total5.toFixed(2));
        $( api.column( 7 ).footer() ).html(total6.toFixed(2));
        $( api.column( 8 ).footer() ).html(total7.toFixed(2));",
        "}"
        ))
      ))
}

shinyApp(ui = ui, server = server)

最终解决方案:

list1=[['a'], ['b'], ['c'], ['d']] 
list2=[['e'], ['f'], ['g']] 

file.csv= 
a
b
c
d
e
f
g

我意识到这可能是JS的不良形式,但是,在我的情况下,这最有效,因此我可以对每个应用不同的选项(某些货币符号,某些平均值,不同的小数精度等)。

2 个答案:

答案 0 :(得分:2)

为了显示页脚中的总和/总数,您必须在表格中添加一个容器,如下所示。我还更改了JS代码:下面提供的版本必须正常工作。不幸的是,我不知道你的JS代码有什么问题,因为我不是javascript的人。您可以使用HTML(...)部分来更改总和的显示。

server <- function(input, output, session) {

# server-side processing
  mtcars2 = mtcars[, 1:8]
      sketch = htmltools::withTags(table(tableFooter(c("",0,0,0,0,0,0,0,0))))
      output$x3 = DT::renderDataTable(DT::datatable(mtcars2, container = sketch,
                                                    extensions = 'Buttons',
                                                    options = list(
                                                      scrollX = TRUE,
                                                      scrollY = TRUE,
                                                      pageLength = 10,
                                                      order = list(list(1, 'asc')),
                                                      fixedHeader = TRUE,
                                                      dom = 'Blrtip',
                                                      buttons = c('copy', 'csv', 'excel', 'pdf', 'print')

                                                      footerCallback =  JS(
                                                    "function( tfoot, data, start, end, display ) {",
                                                    "var api = this.api();",
                                                    "$( api.column( 1 ).footer() ).html(",
                                                    "api.column( 1).data().reduce( function ( a, b ) {",
                                                    "return a + b;",
                                                    "} )",
                                                    ");",
                                                    "$( api.column( 2 ).footer() ).html(",
                                                    "api.column( 2 ).data().reduce( function ( a, b ) {",
                                                    "return a + b;",
                                                    "} )",
                                                    ");",
                                                    "$( api.column( 3 ).footer() ).html(",
                                                    "api.column( 3 ).data().reduce( function ( a, b ) {",
                                                    "return a + b;",
                                                    "} )",
                                                    ");",
                                                    "$( api.column( 4 ).footer() ).html(",
                                                    "api.column( 4 ).data().reduce( function ( a, b ) {",
                                                    "return a + b;",
                                                    "} )",
                                                    ");",
                                                    "$( api.column( 5 ).footer() ).html(",
                                                    "api.column( 5 ).data().reduce( function ( a, b ) {",
                                                    "return a + b;",
                                                    "} )",
                                                    ");",
                                                    "$( api.column( 6 ).footer() ).html(",
                                                    "api.column( 6 ).data().reduce( function ( a, b ) {",
                                                    "return a + b;",
                                                    "} )",
                                                    ");",
                                                    "$( api.column( 7 ).footer() ).html(",
                                                    "api.column( 7 ).data().reduce( function ( a, b ) {",
                                                    "return a + b;",
                                                    "} )",
                                                    ");",
                                                    "$( api.column( 8 ).footer() ).html(",
                                                    "api.column( 8 ).data().reduce( function ( a, b ) {",
                                                    "return a + b;",
                                                    "} )",
                                                    ");",
                                                    "}")
                                                )       
  )
  )
}

答案 1 :(得分:0)

我精心设计了此功能,作为有关总计和格式的可能解决方案。如果需要运行复杂的操作,只需先运行代码,然后将值插入为operation = "custom"。希望对您有所帮助。

library(DT)
dat <- iris[1:4]

sketch <- htmltools::tags$table(
  tableHeader(names(dat)),
  tableFooter(rep("", ncol(dat))))

js_op <- function(column, operation, name = "", signif = 3) {

      # Auxiliar function for mean
      aux <- ifelse(
        operation == "mean", 
        paste0("map(function(num) { return num/data.length; })."), "")

      # Decimals to consider
      signif <- 10^signif

      # Operation
      if (operation %in% c("sum", "mean"))
        operation <- paste0("Math.round((a+b)*",signif,")/",signif)
      if (operation == "count")
        operation <- "data.length"
      if (operation == "custom")
        return(paste0("$(api.column(", column, ").footer()).html('", name, "')"))

      # Result
      res <- paste0(
        "$(api.column(", column, ").footer()).html('", name, "'+",
        "api.column(", column, ").data().", aux, "reduce( function ( a, b ) {",
        "return ", operation, ";",
        "} ));")  
      return(res)
    }

javascript <- JS(
      "function(tfoot, data, start, end, display ) {",
      "var api = this.api(), data;",
      js_op(0, operation = "count", name = "Counter: "),
      js_op(1, operation = "sum", name = "Sum: "),
      js_op(2, operation = "mean", name = "Mean: "),
      js_op(3, operation = "custom", name = "Something"),
      ";}")

datatable(iris[,1:4], rownames = FALSE, container = sketch, 
              options = list(footerCallback = javascript))