从可编辑的数据表中替换初始数据框,然后在另一个表中使用该新数据框

如何解决从可编辑的数据表中替换初始数据框,然后在另一个表中使用该新数据框

我的Shiny应用程序中有一个嵌套的DataTable。子表中的某些列可由用户编辑。此处的目标是让用户编辑值,然后将数据框替换为这些新值。然后,我想将替换后的数据框用于另一个表。我需要在另一个表中使用编辑后的值进行计算。

工作流程

create nested data table -> user edits values -> initial data is replaced by new data -> use the new data for another table

我尝试使用reactiveValues()dataTableProxy()replaceData()observeEvert()来遵循该工作流程,但是没有运气。

# Parent table
structure(list(Market = c("ABILENE-SWEETWATER","ALBANY-SCHENECTADY-TROY,NY"
),`Gross CPP` = c("$1.94","$7.89"),`Gross CPM` = c("$1.02","$0.82"),`Historical Composite Gross CPP (if applicable)` = c("$0","$0"),`Historical Composite Gross CPM (if applicable)` = c("$0","$0")),.Names = c("Market","Gross CPP","Gross CPM","Historical Composite Gross CPP (if applicable)","Historical Composite Gross CPM (if applicable)"),row.names = c(NA,-2L),class = "data.frame")

# Child table
structure(list(Market = c("ABILENE-SWEETWATER","ABILENE-SWEETWATER",NY",NY"),Daypart = c("Daytime","Early Fringe","Early Morning","Early News","Late Fringe","Late News","Prime Access","Prime Time","tv_2","tv_3","tv_cross_screen","Daytime","tv_cross_screen"),`Mix (%)` = c(15,10,15,5,0),`Spot:30 (%)` = c(15,`Spot:15 (%)` = c(0,0
),`Gross CPP ($)` = c(18,18,16,23,24,40,26,44,77,71,61,78,109,145,93,213,`Gross CPM ($)` = c(1.57,1.57,1.39,2,2.09,3.49,2.27,3.83,21,13,6.71,6.19,5.32,6.8,9.5,12.63,8.1,18.56,13),`Historical Composite CPP ($)` = c(0,`Historical Composite CPM ($)` = c(0,0)),"Daypart","Mix (%)","Spot:30 (%)","Spot:15 (%)","Gross CPP ($)","Gross CPM ($)","Historical Composite CPP ($)","Historical Composite CPM ($)"
),class = "data.frame",-22L))

  # Module to create the nested structure of the table
  NestedData <- function(dat,children) {
    stopifnot(length(children) == nrow(dat))
    g <- function(d){
      if(is.data.frame(d)){
        purrr::transpose(d)
      }else{
        purrr::transpose(NestedData(d[[1]],children = d$children))
      }
    }
    subdats <- lapply(children,g)
    oplus <- sapply(subdats,function(x) if(length(x)) "<img src=\'https://raw.githubusercontent.com/DataTables/DataTables/master/examples/resources/details_open.png\'/>" else "")
    cbind(" " = oplus,dat,"_details" = I(subdats),stringsAsFactors = FALSE)
  }
  # Bind the market level and mix breakout data together for the final table
  market_mix_table <- reactive({
    # Take a dependency on input$goButton
    input$goButton
    isolate({
      # The rolled up market view - Parent table
      parent <- market_level_view()
      # The daypart breakout for each market - Child table
      child <- mix_breakout_digital_elements()
      # Make the dataframe
      # This must be met length(children) == nrow(dat)
      Dat <- NestedData(
        dat = parent,children = split(child,child$Market)
      )
      return(Dat)
    })
  })
  # Render the table
  output$daypartTable <- DT::renderDataTable({
    # Whether to show row names (set TRUE or FALSE)
    rowNames <- FALSE
    colIdx <- as.integer(rowNames)
    # The data
    Dat <- market_mix_table()
    parentRows <- which(Dat[,1] != "")
    excelTitle <- paste(
      input$name,input$medium,input$quarter,"Market CPM-CPP Breakout",sep=" "
    )
    ## If the JS stops working take the coed and put it here
    callback_js = JS(
      "var ok = true;","function onUpdate(updatedCell,updatedRow,oldValue) {","  var column = updatedCell.index().column;","  if(column === 8){","    ok = false;","  }else if(column === 7){","    ok = true;","  }","}",sprintf("var parentRows = [%s];",toString(parentRows-1)),sprintf("var j0 = %d;",colIdx),"var nrows = table.rows().count();","for(var i=0; i < nrows; ++i){","  if(parentRows.indexOf(i) > -1){","    table.cell(i,j0).nodes().to$().css({cursor: 'pointer'});","  }else{",j0).nodes().to$().removeClass('details-control');","","// make the table header of the nested table","var format = function(d,childId){","  if(d != null){","    var html = ","      '<table class=\"display compact hover\" ' + ","      'style=\"padding-left: 30px;\" id=\"' + childId + '\"><thead><tr>';","    for(var key in d[d.length-1][0]){","      html += '<th>' + key + '</th>';","    }","    html += '</tr></thead><tfoot><tr>'","      html += '<th></th>';","    return html + '</tr></tfoot></table>';","  } else {","    return '';","};","// row callback to style the rows of the child tables","var rowCallback = function(row,displayNum,index){","  if($(row).hasClass('odd')){","    $(row).css('background-color','white');","    $(row).hover(function(){","      $(this).css('background-color','lightgreen');","    },function() {","    });",'lightblue');","// header callback to style the header of the child tables","var headerCallback = function(thead,data,start,end,display){","  $('th',thead).css({","    'color': 'black',","    'background-color': 'white'","  });","// make the datatable","var format_datatable = function(d,childId,rowIdx){","  // footer callback to display the totals","  // and update the parent row","  var footerCallback = function(tfoot,"    $('th',tfoot).css('background-color','#F5F2F2');","    var api = this.api();","// update the Override CPM when the Override CPP is changed","    var col_override_cpp = api.column(7).data();","    var col_population = api.column(9).data();","    if(ok){","      for(var i = 0; i < col_override_cpp.length; i++){","        api.cell(i,8).data(((parseFloat(col_override_cpp[i])*100)/(parseFloat(col_population[i])/1000)).toFixed(2));","      }","// update the Override CPP when the Override CPM is changed","    var col_override_cpm = api.column(8).data();","    for(var i = 0; i < col_override_cpm.length; i++){","      api.cell(i,7).data(((parseFloat(col_override_cpm[i])*parseFloat(col_population[i])/1000)/100).toFixed(0));","// Update the spot mixes","    var col_mix_percentage = api.column(2).data();","    var col_mix60_mix30 = api.column(10).data();","    var col_mix30_mix15 = api.column(11).data();","    for(var i = 0; i < col_mix_percentage.length; i++){",3).data((parseFloat(col_mix_percentage[i])*parseFloat(col_mix60_mix30[i])).toFixed(1));",4).data((parseFloat(col_mix_percentage[i])*parseFloat(col_mix30_mix15[i])).toFixed(1));","    var child_col_CPM = api.column(6).data();","    for(var i = 0; i < child_col_CPM.length; i++){",6).data(parseFloat(child_col_CPM[i]).toFixed(2));",# "    parseFloat(api.column(5)).toFixed(2)","// Make the footer sums","    api.columns().eq(0).each(function(index){","      if(index == 0) return $(api.column(index).footer()).html('Mix Total');","      var coldata = api.column(index).data();","      var total = coldata","          .reduce(function(a,b){return parseInt(a) + parseInt(b)},0);","      if(index == 3 || index == 4 ||index == 5 || index == 6 || index == 7 || index == 8) {","        $(api.column(index).footer()).html('');","      } else {","        $(api.column(index).footer()).html(total);","      if(total == 100) {","        $(api.column(index).footer()).css({'color': 'green'});","        $(api.column(index).footer()).css({'color': 'red'});","    })","  // update the parent row","    var col_share = api.column(2).data();","    var col_CPP = api.column(5).data();","    var col_CPM = api.column(6).data();","    var col_Historical_CPP = api.column(7).data();","    var col_Historical_CPM = api.column(8).data();","    var CPP = 0,CPM = 0,Historical_CPP = 0,Historical_CPM = 0;","    for(var i = 0; i < col_share.length; i++){","      CPP += (parseInt(col_share[i])*parseInt(col_CPP[i]).toFixed(0));","      CPM += (parseInt(col_share[i])*parseInt(col_CPM[i]).toFixed(2));","      Historical_CPP += (parseInt(col_share[i])*parseInt(col_Historical_CPP[i]).toFixed(0));","      Historical_CPM += (parseInt(col_share[i])*parseInt(col_Historical_CPM[i]).toFixed(2));","    table.cell(rowIdx,j0+3).data((CPP/100).toFixed(2));",j0+4).data((CPM/100).toFixed(2));",j0+5).data((Historical_CPP/100).toFixed(2));",j0+6).data((Historical_CPM/100).toFixed(2));","  var n = d.length - 1;","  var id = 'table#' + childId;","  var columns = Object.keys(d[n][0]).map(function(x){","    return {data: x,title: x};","  if (Object.keys(d[n][0]).indexOf('_details') === -1) {","    var subtable = $(id).DataTable({","                 'data': d[n],"                 'columns': columns,"                 'autoWidth': true,"                 'deferRender': true,"                 'info': false,"                 'lengthChange': false,"                 'ordering': d[n].length > 1,"                 'order': [],"                 'paging': true,"                 'scrollX': false,"                 'scrollY': false,"                 'searching': false,"                 'sortClasses': false,"                 'pageLength': 50,"                 'rowCallback': rowCallback,"                 'headerCallback': headerCallback,"                 'footerCallback': footerCallback,"                 'columnDefs': [","                  {targets: [0,9,11],visible: false},"                  {targets: '_all',className: 'dt-center'}","                 ]","               });","            'data': d[n],"            'columns': columns,"            'autoWidth': true,"            'deferRender': true,"            'info': false,"            'lengthChange': false,"            'ordering': d[n].length > 1,"            'order': [],"            'paging': true,"            'scrollX': false,"            'scrollY': false,"            'searching': false,"            'sortClasses': false,"            'pageLength': 50,"            'rowCallback': rowCallback,"            'headerCallback': headerCallback,"            'footerCallback': footerCallback,"            'columnDefs': [","              {targets: [0,"              {targets: -1,"              {targets: 0,orderable: false,className: 'details-control'},"              {targets: '_all',"             ]","          }).column(0).nodes().to$().css({cursor: 'pointer'});","  subtable.MakeCellsEditable({","    onUpdate: onUpdate,"    inputCss: 'my-input-class',"    columns: [2,7,8],"    confirmationButton: {","      confirmCss: 'my-confirm-class',"      cancelCss: 'my-cancel-class'","// display the child table on click","// array to store the id's of the already created child tables","var children = [];","table.on('click','td.details-control',function(){","  var tbl = $(this).closest('table'),"      tblId = tbl.attr('id'),"      td = $(this),"      row = $(tbl).DataTable().row(td.closest('tr')),"      rowIdx = row.index();","  if(row.child.isShown()){","    row.child.hide();","    td.html('<img src=\"https://raw.githubusercontent.com/DataTables/DataTables/master/examples/resources/details_open.png\"/>');","    var childId = tblId + '-child-' + rowIdx;","// this child table has not been created yet","    if(children.indexOf(childId) === -1){","      children.push(childId);","      row.child(format(row.data(),childId)).show();","    td.html('<img src=\"https://raw.githubusercontent.com/DataTables/DataTables/master/examples/resources/details_close.png\"/>');","      format_datatable(row.data(),rowIdx);","    }else{","      row.child(true);","});"
    )
    # Download button
    downloadButtonJS <-  c(
      "function(xlsx) {","  var table = $('#daypartTable').find('table').DataTable();","  // Letters for Excel columns.","  var LETTERS = [","    'A','B','C','D','E','F','G','H','I','J','K','L','M',"    'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'","  ];","  // Get sheet.","  var sheet = xlsx.xl.worksheets['sheet1.xml'];","  // Get a clone of the sheet data.        ","  var sheetData = $('sheetData',sheet).clone();","  // Clear the current sheet data for appending rows.","  $('sheetData',sheet).empty();","  // Row count in Excel sheet.","  var rowCount = 1;","  // Iterate each row in the sheet data.","  $(sheetData).children().each(function (index) {","    // Used for DT row() API to get child data.","    var rowIndex = index - 2;",#
      "    // Don't process row if its the header row.",sprintf("    if (index > 1 && index < %d) {",nrow(Dat)+2),#
      "      // Get row","      var row = $(this.outerHTML);","      // Set the Excel row attr to the current Excel row count.","      row.attr('r',rowCount);","      // Iterate each cell in the row to change the row number.","      row.children().each(function (index) {","        var cell = $(this);","        // Set each cell's row value.","        var rc = cell.attr('r');","        rc = rc.replace(/\\d+$/,\"\") + rowCount;","        cell.attr('r',rc);","      });","      // Get the row HTML and append to sheetData.","      row = row[0].outerHTML;","      $('sheetData',sheet).append(row);","      rowCount++;","      // Get the child data - could be any data attached to the row.","      // Basically this grabd all the rows of data",sprintf("      var childData = table.row(':eq(' + rowIndex + ')').data()[%d];",ncol(Dat)-1),"      if (childData.length > 0) {","        var colNames = Object.keys(childData[0]).slice(1,9);","        // Prepare Excel formatted row","        headerRow = '<row r=\"' + rowCount +","          '\"><c t=\"inlineStr\" r=\"A' + rowCount +","          '\"><is><t></t></is></c>';","        for(var i = 0; i < colNames.length; i++){","          headerRow = headerRow +","            '<c t=\"inlineStr\" r=\"' + LETTERS[i+1] + rowCount +","            '\" s=\"7\"><is><t>' + colNames[i] +","            '</t></is></c>';","        }","        headerRow = headerRow + '</row>';","        // Append header row to sheetData.","        $('sheetData',sheet).append(headerRow);","        rowCount++; // Inc excelt row counter.","      // The child data is an array of rows","      for (let c = 0; c < childData.length; c++) {","        // Get row data.","        var child = childData[c];","        var childRow = '<row r=\"' + rowCount +","        for(let i = 0; i < colNames.length; i++){","          childRow = childRow +","            '\" s=\"5\"><is><t>' + child[colNames[i]] +","        childRow = childRow + '</row>';","        // Append row to sheetData.",sheet).append(childRow);","        rowCount++; // Inc excel row counter.","      // Just append the header row and increment the excel row counter.","    } else {",sheet).append(this.outerHTML);","}"
    )
    # Table
    table <- DT::datatable(
      Dat,callback = callback_js,rownames = rowNames,escape = -colIdx-1,style = "bootstrap4",extensions = 'Buttons',options = list(
        dom = "Bt",columnDefs = list(
          list(width = '30px',targets = 0),list(width = '330px',targets = 1),list(visible = FALSE,targets = ncol(Dat)-1+colIdx),list(orderable = FALSE,className = 'details-control',targets = colIdx),list(className = "dt-center",targets = "_all")
        ),buttons = list(
          list(
            extend = "excel",className = 'btn btn-primary glyphicon glyphicon-download-alt',text = " Export",exportOptions = list(
              orthogonal = "export",columns = 0:(ncol(Dat)-2)
            ),title = excelTitle,orientation = "landscape",customize = JS(downloadButtonJS)
          )
        ),lengthMenu = list(c(-1,20),c("All",20))
      )
    )
    # Call the html tools deps (js & css files in this directory)
    cell_edit_dep <- htmltools::htmlDependency(
      "CellEdit","1.0.19",src = 'www/',script = "dataTables.cellEdit.js",stylesheet = "dataTables.cellEdit.css"
    )
    table$dependencies <- c(table$dependencies,list(cell_edit_dep))
    
    table %>% formatStyle(
      c(MARKET[2],'Population',SQAD_CPP_DOLLAR,SQAD_CPM_DOLLAR,OVERRIDE_CPP_DOLLAR,OVERRIDE_CPM_DOLLAR),target = 'row',backgroundColor = "#F5F2F2"
    )
  },server = FALSE)
  
  ### This is where I am trying to save the edits to the table and
  ### use those new values for the below table 
  output$market_costings_gross_net_table <- renderTable({
    # Get the data from reative function
    market_costings <- market_level_view()
    reactive_market_costings <- reactiveValues(data = market_costings)
    
    proxy <- dataTableProxy("daypartTable")
    
    observeEvent(input$tableRefresh,{
      DT::replaceData(proxy,reactive_market_costings$data)
    })
  })

解决方法

第一轮

要获取Shiny中的数据:

  • footerCallback函数的末尾添加以下行:

    "    Shiny.setInputValue('data:nestedData',table.data().toArray());",
  • 在“闪亮”应用之前,添加:

  library(jsonlite)

  registerInputHandler(
    "nestedData",function(data,...){
      fromJSON(toJSON(data))
    },force = TRUE
  )
  • 然后数据在input[["data"]]中可用:
  observe({
    print(input[["data"]])
  })

如果您需要更多帮助,请编辑您的帖子以使代码可重复。我没有此代码的最新版本。


第二轮

如我的评论所述,最好在toFixed选项中使用render。我还将可编辑单元格的类型设置为number,这样,已编辑单元格的值就不会转换为字符串,并且在编辑框中还有旋转箭头。

library(DT)

df_children <-
  structure(
    list(
      Market = c(
        "ABILENE-SWEETWATER","ABILENE-SWEETWATER","ALBANY-SCHENECTADY-TROY,NY",NY"
      ),Daypart = c(
        "Daytime","Early Fringe","Early Morning","Early News","Late Fringe","Late News","Prime Access","Prime Time","tv_2","tv_3","tv_cross_screen","Daytime","tv_cross_screen"
      ),`Mix (%)` = c(15,10,15,5,0),`Spot:30 (%)` = c(15,`Spot:15 (%)` = c(0,`Gross CPP ($)` = c(
        18,18,16,23,24,40,26,44,77,71,61,78,109,145,93,213,0
      ),`Gross CPM ($)` = c(
        1.57,1.57,1.39,2,2.09,3.49,2.27,3.83,21,13,6.71,6.19,5.32,6.8,9.5,12.63,8.1,18.56,13
      ),`Historical Composite CPP ($)` = c(0,`Historical Composite CPM ($)` = c(0,population = c(
        47200L,47200L,162700L,162700L
      ),slider_60s = c(
        0.4,0.4,0.4
      ),slider_30s = c(
        0.6,0.6,0.6
      )
    ),.Names = c(
      "Market","Daypart","Mix (%)","Spot:30 (%)","Spot:15 (%)","Gross CPP ($)","Gross CPM ($)","Historical Composite CPP ($)","Historical Composite CPM ($)","population","slider_60s","slider_30s"
    ),class = "data.frame",row.names = c(NA,-22L)
  )

df_parent <-
  structure(
    list(
      Market = c("ABILENE-SWEETWATER",NY"),`Gross CPP` = c(1.94,7.89),`Gross CPM` = c(1.02,0.82),`Historical Composite Gross CPP (if applicable)` = c(0,`Historical Composite Gross CPM (if applicable)` = c(0,0)
    ),"Gross CPP","Gross CPM","Historical Composite Gross CPP (if applicable)","Historical Composite Gross CPM (if applicable)"
    ),-2L),class = "data.frame"
  )

# function to make the required dataframe
NestedData <- function(dat,children){
  stopifnot(length(children) == nrow(dat))
  g <- function(d){
    if(is.data.frame(d)){
      purrr::transpose(d)
    }else{
      purrr::transpose(NestedData(d[[1]],children = d$children))
    }
  }
  subdats <- lapply(children,g)
  oplus <- sapply(subdats,function(x) if(length(x)) "&oplus;" else "")
  cbind(" " = oplus,dat,"_details" = I(subdats),stringsAsFactors = FALSE)
}

# make the required dataframe
# one must have: length(children) == nrow(dat)
Dat <- NestedData(
  dat = df_parent,children = split(df_children,df_children$Market)
)

## whether to show row names (set TRUE or FALSE)
rowNames <- FALSE
colIdx <- as.integer(rowNames)

## make the callback
parentRows <- which(Dat[,1] != "")

callback_js = JS(
  "var ok = true;","function onUpdate(updatedCell,updatedRow,oldValue) {","  var column = updatedCell.index().column;","  if(column === 8){","    ok = false;","  }else if(column === 7){","    ok = true;","  }","}","function render0(data,type,row) {",# @Timothy,new
  "  if(type === 'display') {","    return parseFloat(data).toFixed(0);","  } else {","    return data;","function render2(data,"    return parseFloat(data).toFixed(2);",sprintf("var parentRows = [%s];",toString(parentRows-1)),sprintf("var j0 = %d;",colIdx),"var nrows = table.rows().count();","for(var i=0; i < nrows; ++i){","  if(parentRows.indexOf(i) > -1){","    table.cell(i,j0).nodes().to$().css({cursor: 'pointer'});","  }else{",j0).nodes().to$().removeClass('details-control');","","// make the table header of the nested table","var format = function(d,childId){","  if(d != null){","    var html = ","      '<table class=\"display compact hover\" ' + ","      'style=\"padding-left: 30px;\" id=\"' + childId + '\"><thead><tr>';","    for(var key in d[d.length-1][0]){","      html += '<th>' + key + '</th>';","    }","    html += '</tr></thead><tfoot><tr>'","      html += '<th></th>';","    return html + '</tr></tfoot></table>';","    return '';","};","// row callback to style the rows of the child tables","var rowCallback = function(row,displayNum,index){","  if($(row).hasClass('odd')){","    $(row).css('background-color','white');","    $(row).hover(function(){","      $(this).css('background-color','lightgreen');","    },function() {","    });",'lightblue');","// header callback to style the header of the child tables","var headerCallback = function(thead,data,start,end,display){","  $('th',thead).css({","    'color': 'black',","    'background-color': 'white'","  });","// make the datatable","var format_datatable = function(d,childId,rowIdx){","  // footer callback to display the totals","  // and update the parent row","  var footerCallback = function(tfoot,I removed all the 'toFixed'
  "    $('th',tfoot).css('background-color','#F5F2F2');","    var api = this.api();","// update the Override CPM when the Override CPP is changed","    var col_override_cpp = api.column(7).data();","    var col_population = api.column(9).data();","    if(ok){","      for(var i = 0; i < col_override_cpp.length; i++){","        api.cell(i,8).data(((parseFloat(col_override_cpp[i])*100)/(parseFloat(col_population[i])/1000)));","      }","// update the Override CPP when the Override CPM is changed","    var col_override_cpm = api.column(8).data();","    for(var i = 0; i < col_override_cpm.length; i++){","      api.cell(i,7).data(((parseFloat(col_override_cpm[i])*parseFloat(col_population[i])/1000)/100));","// Update the spot mixes","    var col_mix_percentage = api.column(2).data();","    var col_mix60_mix30 = api.column(10).data();","    var col_mix30_mix15 = api.column(11).data();","    for(var i = 0; i < col_mix_percentage.length; i++){",3).data((parseFloat(col_mix_percentage[i])*parseFloat(col_mix60_mix30[i])));",4).data((parseFloat(col_mix_percentage[i])*parseFloat(col_mix30_mix15[i])));","    var child_col_CPM = api.column(6).data();","    for(var i = 0; i < child_col_CPM.length; i++){",6).data(parseFloat(child_col_CPM[i]));","// Make the footer sums","    api.columns().eq(0).each(function(index){","      if(index == 0) return $(api.column(index).footer()).html('Mix Total');","      var coldata = api.column(index).data();","      var total = coldata","          .reduce(function(a,b){return parseFloat(a) + parseFloat(b);},0);","      if(index == 3 || index == 4 ||index == 5 || index == 6 || index == 7 || index == 8) {","        $(api.column(index).footer()).html('');","      } else {","        $(api.column(index).footer()).html(total);","      if(total == 100) {","        $(api.column(index).footer()).css({'color': 'green'});","        $(api.column(index).footer()).css({'color': 'red'});","    })","  // update the parent row",I replaced everywhere parseInt with parseFloat
  "    var col_share = api.column(2).data();","    var col_CPP = api.column(5).data();","    var col_CPM = api.column(6).data();","    var col_Historical_CPP = api.column(7).data();","    var col_Historical_CPM = api.column(8).data();","    var CPP = 0,CPM = 0,Historical_CPP = 0,Historical_CPM = 0;","    for(var i = 0; i < col_share.length; i++){","      CPP += (parseFloat(col_share[i])*parseFloat(col_CPP[i]));","      CPM += (parseFloat(col_share[i])*parseFloat(col_CPM[i]));","      Historical_CPP += (parseFloat(col_share[i])*parseFloat(col_Historical_CPP[i]));","      Historical_CPM += (parseFloat(col_share[i])*parseFloat(col_Historical_CPM[i]));","    table.cell(rowIdx,j0+2).data(CPP/100);",there were errors here (it's j0 + 2/3/4/5)
  "    table.cell(rowIdx,j0+3).data(CPM/100);",j0+4).data(Historical_CPP/100);",j0+5).data(Historical_CPM/100);","    Shiny.setInputValue('data:nestedData',"  var n = d.length - 1;","  var id = 'table#' + childId;","  var columns = Object.keys(d[n][0]).map(function(x){","    return {data: x,title: x};","  var subtable = $(id).DataTable({","                 'data': d[n],"                 'columns': columns,"                 'autoWidth': true,"                 'deferRender': true,"                 'info': false,"                 'lengthChange': false,"                 'ordering': d[n].length > 1,"                 'order': [],"                 'paging': true,"                 'scrollX': false,"                 'scrollY': false,"                 'searching': false,"                 'sortClasses': false,"                 'pageLength': 50,"                 'rowCallback': rowCallback,"                 'headerCallback': headerCallback,"                 'footerCallback': footerCallback,"                 'columnDefs': [","                  {targets: [2,3,4],render: render0},new
  "                  {targets: [5,6,7,8],render: render2},new
  "                  {targets: [0,9,11],visible: false},"                  {targets: '_all',className: 'dt-center'}","                 ]","               });","  subtable.MakeCellsEditable({","    onUpdate: onUpdate,"    inputCss: 'my-input-class',"    columns: [2,"    inputTypes: [",new 
  "      {column: 2,type: 'number'},"      {column: 7,"      {column: 8,type: 'number'}","    ],"    confirmationButton: {","      confirmCss: 'my-confirm-class',"      cancelCss: 'my-cancel-class'","// display the child table on click","// array to store the id's of the already created child tables","var children = [];","table.on('click','td.details-control',function(){","  var tbl = $(this).closest('table'),"      tblId = tbl.attr('id'),"      td = $(this),"      row = $(tbl).DataTable().row(td.closest('tr')),"      rowIdx = row.index();","  if(row.child.isShown()){","    row.child.hide();","    td.html('<img src=\"https://raw.githubusercontent.com/DataTables/DataTables/master/examples/resources/details_open.png\"/>');","    var childId = tblId + '-child-' + rowIdx;","// this child table has not been created yet","    if(children.indexOf(childId) === -1){","      children.push(childId);","      row.child(format(row.data(),childId)).show();","    td.html('<img src=\"https://raw.githubusercontent.com/DataTables/DataTables/master/examples/resources/details_close.png\"/>');","      format_datatable(row.data(),rowIdx);","    }else{","      row.child(true);","});"
)


render_js <- JS( # @Timothy,new
  "function(data,"  if(type === 'display') {","    return '$' + data.toFixed(2);","}"
)


## the datatable
dtable <- datatable(
  Dat,callback = callback_js,rownames = rowNames,escape = -colIdx-1,extensions = "Buttons",options = list(
    dom = "Bfrtip",columnDefs = list(
      list(render = render_js,targets = colIdx + 1 + 1:4),new
      list(visible = FALSE,targets = ncol(Dat)-1+colIdx),list(orderable = FALSE,className = 'details-control',targets = colIdx),list(className = "dt-center",targets = "_all")
    )
  )
)

path <- "~/Work/R/DT" # folder containing the files dataTables.cellEdit.js
                      # and dataTables.cellEdit.css
dep <- htmltools::htmlDependency(
  "CellEdit","1.0.19",path,script = "dataTables.cellEdit.js",stylesheet = "dataTables.cellEdit.css")
dtable$dependencies <- c(dtable$dependencies,list(dep))






library(shiny)
library(jsonlite)

registerInputHandler(
  "nestedData",...){
    fromJSON(toJSON(data))
  },force = TRUE
)

ui <- fluidPage(
  br(),DTOutput("dtable")
)

server <- function(input,output){
  
  output[["dtable"]] <- renderDT(dtable)
  
  observe({
    print(input[["data"]])
  })
  
}

shinyApp(ui,server)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res