Downloading a Nested DT table in Shiny - r

I've got a nested DT table in my Shiny app. The child table is a list that gets passed and rendered into the table. When I go to add a download button via DT's built in method, the output contains the parent table data and then a list of [Object][Object].. instead of the actual child data.
Do I have to write my own downloadable button method instead of using DT's method or is there a original DT method that helps with this? Haven't found a solution yet.
Data
Parent
structure(list(Market = c("ABILENE, TX", "AKRON, OH"), `SQAD CPP ($)` = c(10,
49), `SQAD CPM ($)` = c(22, 30), `Override CPP ($)` = c(0, 0),
`Override CPM ($)` = c(0, 0)), .Names = c("Market", "SQAD CPP ($)",
"SQAD CPM ($)", "Override CPP ($)", "Override CPM ($)"), row.names = c(NA,
-2L), class = "data.frame")
Child
structure(list(Market = c("ABILENE, TX", "ABILENE, TX", "ABILENE, TX",
"ABILENE, TX", "ABILENE, TX", "ABILENE, TX", "ABILENE, TX", "ABILENE, TX",
"ABILENE, TX", "AKRON, OH", "AKRON, OH", "AKRON, OH", "AKRON, OH",
"AKRON, OH", "AKRON, OH", "AKRON, OH", "AKRON, OH", "AKRON, OH"
), Daypart = c(" Podcast", " Streaming/Digital Audio", "Afternoon Drive",
"Daytime", "Evening", "Mon-Fri Average", "Mon-Sun Average", "Morning Drive",
"Weekend", " Podcast", " Streaming/Digital Audio", "Afternoon Drive",
"Daytime", "Evening", "Mon-Fri Average", "Mon-Sun Average", "Morning Drive",
"Weekend"), `Mix (%)` = c(10L, 10L, 10L, 10L, 10L, 10L, 5L, 15L,
10L, 10L, 10L, 10L, 10L, 10L, 10L, 5L, 15L, 10L), `Spot:60 (%)` = c(4,
4, 4, 4, 4, 4, 2, 6, 4, 4, 4, 4, 4, 4, 4, 2, 6, 4), `Spot:30 (%)` = c(6,
6, 6, 6, 6, 6, 3, 9, 6, 6, 6, 6, 6, 6, 6, 3, 9, 6), `SQAD CPP ($)` = c(10,
6, 27, 31, 44, 32, 31, 26, 26, 34, 21, 170, 156, 112, 151, 136,
177, 95), `SQAD CPM ($)` = c(21, 13, 57.6, 64.8, 93.6, 68.4,
64.8, 54, 54, 21, 13, 104.5, 96.1, 69, 93, 83.6, 108.7, 58.5),
`Override CPP ($)` = c(10, 6, 27, 31, 44, 32, 31, 26, 26,
34, 21, 170, 156, 112, 151, 136, 177, 95), `Override CPM ($)` = c(21,
13, 57.63, 64.83, 93.64, 68.43, 64.83, 54.03, 54.03, 21,
13, 104.49, 96.13, 68.96, 92.99, 83.59, 108.67, 58.51), population = c(47200L,
47200L, 47200L, 47200L, 47200L, 47200L, 47200L, 47200L, 47200L,
162700L, 162700L, 162700L, 162700L, 162700L, 162700L, 162700L,
162700L, 162700L), slider_60s = c(0.4, 0.4, 0.4, 0.4, 0.4,
0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4,
0.4), slider_30s = c(0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6,
0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6)), .Names = c("Market",
"Daypart", "Mix (%)", "Spot:60 (%)", "Spot:30 (%)", "SQAD CPP ($)",
"SQAD CPM ($)", "Override CPP ($)", "Override CPM ($)", "population",
"slider_60s", "slider_30s"), class = "data.frame", row.names = c(NA,
-18L))
Code
# 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({
markets <- market_costings_gross_net()
mix_breakout <- mix_breakout_digital_elements()
# Make the dataframe
# This must be met length(children) == nrow(dat)
Dat <- NestedData(
dat = markets,
children = split(mix_breakout, mix_breakout$Market)
)
return(Dat)
})
})
# Render the table
output$daypartTable <- DT::renderDataTable({
Server = FALSE
# 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] != "")
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{",
" table.cell(i,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>'",
" for(var key in d[d.length-1][0]){",
" html += '<th></th>';",
" }",
" return html + '</tr></tfoot></table>';",
" } else {",
" return '';",
" }",
"};",
"",
"// row callback to style the rows of the child tables",
"var rowCallback = function(row, dat, displayNum, index){",
" if($(row).hasClass('odd')){",
" $(row).css('background-color', 'white');",
" $(row).hover(function(){",
" $(this).css('background-color', 'lightgreen');",
" }, function() {",
" $(this).css('background-color', 'white');",
" });",
" } else {",
" $(row).css('background-color', 'white');",
" $(row).hover(function(){",
" $(this).css('background-color', 'lightblue');",
" }, function() {",
" $(this).css('background-color', 'white');",
" });",
" }",
"};",
"",
"// 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, data, start, end, display){",
" $('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(((parseInt(col_override_cpp[i])*100)/(parseInt(col_population[i])/1000)).toFixed(0));",
" }",
" }",
"// 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(((parseInt(col_override_cpm[i])*parseInt(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++){",
" api.cell(i,3).data((parseFloat(col_mix_percentage[i])*parseFloat(col_mix60_mix30[i])).toFixed(1));",
" api.cell(i,4).data((parseFloat(col_mix_percentage[i])*parseFloat(col_mix30_mix15[i])).toFixed(1));",
" }",
"// 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'});",
" } else {",
" $(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(0));",
" 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(0));",
" }",
" table.cell(rowIdx, j0+2).data((CPP/100).toFixed(2));",
" table.cell(rowIdx, j0+3).data((CPM/100).toFixed(2));",
" table.cell(rowIdx, j0+4).data((Historical_CPP/100).toFixed(2));",
" table.cell(rowIdx, j0+5).data((Historical_CPM/100).toFixed(2));",
" }",
" var dataset = [];",
" var n = d.length - 1;",
" for(var i = 0; i < d[n].length; i++){",
" var datarow = $.map(d[n][i], function (value, index) {",
" return [value];",
" });",
" dataset.push(datarow);",
" }",
" var id = 'table#' + childId;",
" if (Object.keys(d[n][0]).indexOf('_details') === -1) {",
" var subtable = $(id).DataTable({",
" 'data': dataset,",
" '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, 10, 11], visible: false},",
" {targets: '_all', className: 'dt-center'}",
" ]",
" });",
" } else {",
" var subtable = $(id).DataTable({",
" 'data': dataset,",
" '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, 10, 11], visible: false},",
" {targets: -1, visible: false},",
" {targets: 0, orderable: false, className: 'details-control'},",
" {targets: '_all', className: 'dt-center'}",
" ]",
" }).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",
"var children = [];", # array to store the id's of the already created child tables
"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\"/>');",
" } else {",
" var childId = tblId + '-child-' + rowIdx;",
" if(children.indexOf(childId) === -1){", # this child table has not been created yet
" 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(), childId, rowIdx);",
" }else{",
" row.child(true);",
" td.html('<img src=\"https://raw.githubusercontent.com/DataTables/DataTables/master/examples/resources/details_close.png\"/>');",
" }",
" }",
"});"
)
# Table
table <- DT::datatable(
Dat,
callback = callback_js,
rownames = rowNames,
escape = -colIdx-1,
style = "bootstrap4",
extensions = 'Buttons',
options = list(
dom = "Blfrtip",
buttons = list("copy",
list(
extend = "collection",
buttons = "csv",
text = "Download"
)
),
lengthMenu = list(c(-1, 10, 20),
c("All", 10, 20)),
columnDefs = list(
list(width = '30px', targets = 0),
list(width = '545px', targets = 1),
list(visible = FALSE, targets = ncol(Dat)-1+colIdx),
list(orderable = FALSE, className = 'details-control', targets = colIdx),
list(className = "dt-center", targets = "_all")
)
)
)
# 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', 'SQAD CPP ($)', 'SQAD CPM ($)', 'Override CPP ($)', 'Override CPM ($)'),
target = 'row',
backgroundColor = "#F5F2F2"
)
})

Try this:
js <- 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.",
sprintf(" var childData = table.row(':eq(' + rowIndex + ')').data()[%d];", ncol(Dat)-1), #
" if (childData.length > 0) {",
" var colNames = Object.keys(childData[0]);",
" // 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 (c = 0; c < childData.length; c++) {",
" // Get row data.",
" child = childData[c];",
" // Prepare Excel formatted row",
" var colNames = Object.keys(child);",
" childRow = '<row r=\"' + rowCount +",
" '\"><c t=\"inlineStr\" r=\"A' + rowCount +",
" '\"><is><t></t></is></c>';",
" for(var i = 0; i < colNames.length; i++){",
" childRow = childRow +",
" '<c t=\"inlineStr\" r=\"' + LETTERS[i+1] + rowCount +",
" '\" s=\"5\"><is><t>' + child[colNames[i]] +",
" '</t></is></c>';",
" }",
" childRow = childRow + '</row>';",
" // Append row to sheetData.",
" $('sheetData', sheet).append(childRow);",
" rowCount++; // Inc excel row counter.",
" }",
" // Just append the header row and increment the excel row counter.",
" } else {",
" $('sheetData', sheet).append(this.outerHTML);",
" rowCount++;",
" }",
" });",
"}"
)
datatable(
Dat, callback = callback, rownames = rowNames, escape = -colIdx-1,
extensions = "Buttons",
options = list(
dom = "Bfrtip",
columnDefs = list(
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",
exportOptions = list(
orthogonal = "export",
columns = 0:(ncol(Dat)-2)
),
orientation = "landscape",
customize = JS(js)
)
)
)
)
Here is an example of the generated Excel file:
EDIT
Better:
excelTitle <- NULL # set to NULL if you don't want a title
js <- c(
"function(xlsx) {",
" var table = $('#daypartTable').find('table').DataTable();",
" // Number of columns.",
" var ncols = table.columns().count();",
" // Is there a title?",
sprintf(" var title = %s;", ifelse(is.null(excelTitle), "false", "true")),
" // Integer to Excel column: 0 -> A, 1 -> B, ..., 25 -> Z, 26 -> AA, ...",
" var XLcolumn = function(j){", # https://codegolf.stackexchange.com/a/163919
" return j < 0 ? '' : XLcolumn(j/26-1) + String.fromCharCode(j % 26 + 65);",
" };",
" // 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 = title ? index - 2 : index - 1;",
" // Don't process row if it's the title row or the header row.",
" var i0 = title ? 1 : 0;",
" if (index > i0) {",
" // 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.",
" var childData = table.row(':eq(' + rowIndex + ')').data()[ncols-1];",
" if (childData.length > 0) {",
" var colNames = Object.keys(childData[0]);",
" // Prepare Excel formatted row",
" var headerRow = '<row r=\"' + rowCount +",
" '\"><c t=\"inlineStr\" r=\"A' + rowCount +",
" '\"><is><t></t></is></c>';",
" for(let i = 0; i < colNames.length; i++){",
" headerRow = headerRow +",
" '<c t=\"inlineStr\" r=\"' + XLcolumn(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 excel 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];",
" // Prepare Excel formatted row",
" var childRow = '<row r=\"' + rowCount +",
" '\"><c t=\"inlineStr\" r=\"A' + rowCount +",
" '\"><is><t></t></is></c>';",
" var i = 0;",
" for(let colname in child){",
" childRow = childRow +",
" '<c t=\"inlineStr\" r=\"' + XLcolumn(i+1) + rowCount +",
" '\" s=\"5\"><is><t>' + child[colname] +",
" '</t></is></c>';",
" i++;",
" }",
" childRow = childRow + '</row>';",
" // Append row to sheetData.",
" $('sheetData', sheet).append(childRow);",
" rowCount++; // Inc excel row counter.",
" }",
" // Just append the header row and increment the excel row counter.",
" } else {",
" $('sheetData', sheet).append(this.outerHTML);",
" rowCount++;",
" }",
" });",
"}"
)
datatable(
Dat, callback = callback, rownames = rowNames, escape = -colIdx-1,
extensions = "Buttons",
options = list(
dom = "Bfrtip",
columnDefs = list(
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",
exportOptions = list(
orthogonal = "export",
columns = 0:(ncol(Dat)-2)
),
title = excelTitle,
orientation = "landscape",
customize = JS(js)
)
)
)
)
EDIT 2
In callback_js, replace
" var dataset = [];",
" var n = d.length - 1;",
" for(var i = 0; i < d[n].length; i++){",
" var datarow = $.map(d[n][i], function (value, index) {",
" return [value];",
" });",
" dataset.push(datarow);",
" }",
" var id = 'table#' + childId;",
" if (Object.keys(d[n][0]).indexOf('_details') === -1) {",
" var subtable = $(id).DataTable({",
" 'data': dataset,",
" '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, 10, 11], visible: false},",
" {targets: '_all', className: 'dt-center'}",
" ]",
" });",
" } else {",
" var subtable = $(id).DataTable({",
" 'data': dataset,",
" '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, 10, 11], visible: false},",
" {targets: -1, visible: false},",
" {targets: 0, orderable: false, className: 'details-control'},",
" {targets: '_all', className: 'dt-center'}",
" ]",
" }).column(0).nodes().to$().css({cursor: 'pointer'});",
" }",
with
" 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, 10, 11], visible: false},",
" {targets: '_all', className: 'dt-center'}",
" ]",
" });",
" } else {",
" 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, 10, 11], visible: false},",
" {targets: -1, visible: false},",
" {targets: 0, orderable: false, className: 'details-control'},",
" {targets: '_all', className: 'dt-center'}",
" ]",
" }).column(0).nodes().to$().css({cursor: 'pointer'});",
" }",
Moreover, you probably don't want the hidden columns in the Excel file. So replace this code:
" if (childData.length > 0) {",
" var colNames = Object.keys(childData[0]);",
" // Prepare Excel formatted row",
......
" // Append row to sheetData.",
" $('sheetData', sheet).append(childRow);",
" rowCount++; // Inc excel row counter.",
" }",
with
" if (childData.length > 0) {",
" var colNames = Object.keys(childData[0]).slice(1,9);",
" // Prepare Excel formatted row",
" var headerRow = '<row r=\"' + rowCount +",
" '\"><c t=\"inlineStr\" r=\"A' + rowCount +",
" '\"><is><t></t></is></c>';",
" for(let i = 0; i < colNames.length; i++){",
" headerRow = headerRow +",
" '<c t=\"inlineStr\" r=\"' + XLcolumn(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 excel 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];",
" // Prepare Excel formatted row",
" var childRow = '<row r=\"' + rowCount +",
" '\"><c t=\"inlineStr\" r=\"A' + rowCount +",
" '\"><is><t></t></is></c>';",
" for(let i = 0; i < colNames.length; i++){",
" childRow = childRow +",
" '<c t=\"inlineStr\" r=\"' + XLcolumn(i+1) + rowCount +",
" '\" s=\"5\"><is><t>' + child[colNames[i]] +",
" '</t></is></c>';",
" }",
" childRow = childRow + '</row>';",
" // Append row to sheetData.",
" $('sheetData', sheet).append(childRow);",
" rowCount++; // Inc excel row counter.",
" }",
EDIT 3
This doesn't work if there are some periods in the column names of a child table. Here is the fix:
" var columns = Object.keys(d[n][0]).map(function(x){",
" return {data: x.replace('.', '\\\\\\.'), title: x};",
" });",

Related

How to make an R plot of SNPs on the x-axis and beliefs on the y-axis?

How to make an R plot of SNPs on the x-axis and beliefs on the y-axis? Maybe a jitter plot? Or an interactive plotly? If I were using Python, hash table would be the simplest data structure for this. But it looks like R doesn't support such a data structure easily?
dput result:
> dput(head(bel_bpa_df))
structure(list(SNPs = list(c("rs12117661 ", " rs11588151 ", " rs34232196 ",
" rs4500361 ", " rs4927191 ", " rs200159426 ", " rs187607506 ",
" rs12748266 ", " rs11206510 ", " rs34900073 ", " rs55958021 ",
" rs12404395 ", " rs613855 ", " rs624612 ", " rs625619 ", " rs479910"
), c("rs12117661 ", " rs11588151 ", " rs34232196 ", " rs3976734 ",
" rs4500361 ", " rs4927191 ", " rs200159426 ", " rs187607506 ",
" rs12748266 ", " rs11206510 ", " rs34900073 ", " rs2495491 ",
" rs2479415 ", " rs2495489 ", " rs55958021 ", " rs12404395 ",
" rs2479404 ", " rs2479409 ", " rs613855 ", " rs624612 ", " rs625619 ",
" rs479910"), c("rs12117661 ", " rs11588151 ", " rs34232196 ",
" rs4500361 ", " rs4927191 ", " rs200159426 ", " rs187607506 ",
" rs12748266 ", " rs11206510 ", " rs34900073 ", " rs55958021 ",
" rs12404395 ", " rs11206513 ", " rs7530425 ", " rs11436234 ",
" rs10888897 ", " rs7543163 ", " rs11206514 ", " rs11206515 ",
" rs10888898 ", " rs613855 ", " rs624612 ", " rs625619 ", " rs479910"
), c("rs12117661 ", " rs11588151 ", " rs34232196 ", " rs4500361 ",
" rs4927191 ", " rs200159426 ", " rs187607506 ", " rs12748266 ",
" rs11206510 ", " rs34900073 ", " rs55958021 ", " rs12404395 ",
" rs613855 ", " rs624612 ", " rs625619 ", " rs479910 ", " rs568052 ",
" rs483462 ", " rs615563 ", " rs630431 ", " rs662145 ", " 1:55539780_TA_T ",
" rs487230 ", " rs683880 ", " rs555687 ", " rs548852"), c("rs12117661 ",
" rs11588151 ", " rs34232196 ", " rs4500361 ", " rs4927191 ",
" rs200159426 ", " rs187607506 ", " rs12748266 ", " rs11206510 ",
" rs34900073 ", " rs55958021 ", " rs12404395 ", " rs613855 ",
" rs624612 ", " rs625619 ", " rs494198 ", " rs7552841 ", " rs639750 ",
" rs499883 ", " rs521662 ", " rs1165287 ", " rs634272 ", " rs553741 ",
" rs693668 ", " rs471705 ", " rs472495 ", " rs479910"), c("rs17111483 ",
" rs12117661 ", " rs11588151 ", " rs34232196 ", " rs4500361 ",
" rs4927191 ", " rs200159426 ", " rs199717562 ", " rs200730299 ",
" rs187607506 ", " rs60228221 ", " rs57498787 ", " rs12141643 ",
" rs4609471 ", " rs12748266 ", " rs11206510 ", " rs34900073 ",
" rs55958021 ", " rs12404395 ", " rs28385708 ", " rs613855 ",
" rs624612 ", " rs625619 ", " rs479910 ", " rs11206517 ", " rs12067569 ",
" rs10465832 ", " rs56235208 ", " rs72911441")), Belief = c(0.531441,
0.59049, 0.59049, 0.59049, 0.59049, 0.59049), Plausibility = c(1,
1, 1, 1, 1, 1), `Plty Ratio` = c(2.13420294989532, 2.4419428096994,
2.4419428096994, 2.4419428096994, 2.4419428096994, 2.4419428096994
)), row.names = c(NA, 6L), class = "data.frame")
Following #akrun's first suggestion bel_bpa_df %>% unnest(SNPs) %>% mutate(SNPs = trimws(SNPs)) %>% ggplot(aes(SNPs, Belief)) + geom_jitter(), I got a plot that's pretty dense. I would be so good if I can look at the individual ids in the x-axis. Would plotly do a better job at this?
To answer your second question, you could rotate the x axis labels and change the font size using theme and guides (you could adjust the font size) like this:
library(dplyr)
library(tidyr)
library(ggplot2)
bel_bpa_df %>%
unnest(SNPs) %>%
mutate(SNPs = trimws(SNPs)) %>%
ggplot(aes(SNPs, Belief)) +
geom_jitter() +
guides(x = guide_axis(angle = 90)) +
theme(axis.text.x = element_text(size = 3))
Created on 2023-01-06 with reprex v2.0.2

How to align column names for parent and child rows in data table in R Shiny app?

I am trying to build an app which has expand and collapse feature. I am able to build this functionality however, the column names for parent and child rows are not in sync. For example, I would want column 'mpg' for Child row should be exactly below the 'mpg' column for Parent row .
Can anyone assist here ?
Here is my code.
library(data.table)
library(DT)
library(shiny)
Df <- mtcars
Df$Flag <- 'C'
Df$Flag[c(1,3,5)] <- 'P'
DfParent <- Df %>% filter(Flag=='P') %>% select(-Flag)
DfParent <- data.table(DfParent)
setkey(DfParent,cyl)
ui <- fluidPage(fluidRow(DT::dataTableOutput(width = "100%", "table")))
server <- function(input, output) {
output$table = DT::renderDataTable({
mtcars_dt = data.table(mtcars)
setkey(mtcars_dt, cyl)
cyl_dt = unique(mtcars_dt[, list(cyl)])
setkey(cyl_dt, cyl)
mtcars_dt =
mtcars_dt[, list("_details" = list(purrr::transpose(.SD))), by = list(cyl)]
mtcars_dt <- DfParent[mtcars_dt]
mtcars_dt[, ' ' := '⊕']
cyl_dt = merge(cyl_dt, mtcars_dt, all.x = TRUE )
setcolorder(cyl_dt, c(length(cyl_dt),c(1:(length(cyl_dt) - 1))))
## the callback
callback = JS(
"table.column(1).nodes().to$().css({cursor: 'pointer'});",
"",
"// make the table header of the nested table",
"var format = function(d, childId){",
" if(d != null){",
" var html = ",
" '<table class=\"display compact hover\" id=\"' + childId + '\"><thead><tr>';",
" for (var key in d[d.length-1][0]) {",
" html += '<th>' + key + '</th>';",
" }",
" html += '</tr></thead></table>'",
" return html;",
" } else {",
" return '';",
" }",
"};",
"",
"// row callback to style the rows of the child tables",
"var rowCallback = function(row, dat, displayNum, index){",
" if($(row).hasClass('odd')){",
" $(row).css('background-color', 'papayawhip');",
" $(row).hover(function(){",
" $(this).css('background-color', '#E6FF99');",
" }, function() {",
" $(this).css('background-color', 'papayawhip');",
" });",
" } else {",
" $(row).css('background-color', 'lemonchiffon');",
" $(row).hover(function(){",
" $(this).css('background-color', '#DDFF75');",
" }, function() {",
" $(this).css('background-color', 'lemonchiffon');",
" });",
" }",
"};",
"",
"// header callback to style the header of the child tables",
"var headerCallback = function(thead, data, start, end, display){",
" $('th', thead).css({",
" 'border-top': '3px solid indigo',",
" 'color': 'indigo',",
" 'background-color': '#fadadd'",
" });",
"};",
"",
"// make the datatable",
"var format_datatable = function(d, childId){",
" var dataset = [];",
" var n = d.length - 1;",
" for(var i = 0; i < d[n].length; i++){",
" var datarow = $.map(d[n][i], function (value, index) {",
" return [value];",
" });",
" dataset.push(datarow);",
" }",
" var id = 'table#' + childId;",
" if (Object.keys(d[n][0]).indexOf('_details') === -1) {",
" var subtable = $(id).DataTable({",
" 'data': dataset,",
" 'autoWidth': true,",
" 'deferRender': true,",
" 'info': false,",
" 'lengthChange': false,",
" 'ordering': d[n].length > 1,",
" 'order': [],",
" 'paging': false,",
" 'scrollX': false,",
" 'scrollY': false,",
" 'searching': false,",
" 'sortClasses': false,",
" 'rowCallback': rowCallback,",
" 'headerCallback': headerCallback,",
" 'columnDefs': [{targets: '_all', className: 'dt-center'}]",
" });",
" } else {",
" var subtable = $(id).DataTable({",
" 'data': dataset,",
" 'autoWidth': true,",
" 'deferRender': true,",
" 'info': false,",
" 'lengthChange': false,",
" 'ordering': d[n].length > 1,",
" 'order': [],",
" 'paging': false,",
" 'scrollX': false,",
" 'scrollY': false,",
" 'searching': false,",
" 'sortClasses': false,",
" 'rowCallback': rowCallback,",
" 'headerCallback': headerCallback,",
" 'columnDefs': [",
" {targets: -1, visible: false},",
" {targets: 0, orderable: false, className: 'details-control'},",
" {targets: '_all', className: 'dt-center'}",
" ]",
" }).column(0).nodes().to$().css({cursor: 'pointer'});",
" }",
"};",
"",
"// display the child table on click",
"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('⊕');",
" } else {",
" var childId = tblId + '-child-' + rowIdx;",
" row.child(format(row.data(), childId)).show();",
" td.html('&CircleMinus;');",
" format_datatable(row.data(), childId);",
" }",
"});")
## datatable
datatable(cyl_dt, callback = callback, escape = -2,
options = list(
columnDefs = list(
list(visible = FALSE, targets = ncol(cyl_dt)),
list(orderable = FALSE, className = 'details-control', targets = 1),
list(className = "dt-center", targets = "_all")
)
))
},server = FALSE)
}
shinyApp (ui = ui, server = server)

where is the missing column when Converting a matrix/array to a data table in R?

I get a matrix/array from an output. My goal is to convert it to a data table and make it print friendly. However, one key column was gone when doing the conversion..
dput(tab)
structure(c(" 1950", " ", " 207 (10.6) ", " 288 (14.8) ",
" 1455 (74.6) ", " ", " 95 ( 4.9) ", " 0 ( 0.0) ",
" 1823 (93.5) ", " 0 ( 0.0) ", " 32 ( 1.6) ", "4721.83 (1322.96)",
" 553", " ", " 27 ( 4.9) ", " 99 (17.9) ", " 427 (77.2) ",
" ", " 68 (12.3) ", " 0 ( 0.0) ", " 455 (82.3) ",
" 0 ( 0.0) ", " 30 ( 5.4) ", "4698.88 (1356.03)", " 813",
" ", " 96 (11.8) ", " 64 ( 7.9) ", " 653 (80.3) ",
" ", " 8 ( 1.0) ", " 0 ( 0.0) ", " 804 (98.9) ",
" 0 ( 0.0) ", " 1 ( 0.1) ", "4957.45 (1259.53)", " 1243",
" ", " 166 (13.4) ", " 191 (15.4) ", " 886 (71.3) ",
" ", " 129 (10.4) ", " 0 ( 0.0) ", " 1098 (88.3) ",
" 0 ( 0.0) ", " 16 ( 1.3) ", "4861.85 (1221.35)", "",
"<0.001", "", "", "", " NaN", "", "", "", "", "", "<0.001",
"", "", "", "", "", "", "", "", "", "", "", ""), .Dim = c(12L,
6L), .Dimnames = list(c("n", "Race (%)", " Black", " Other race",
" White", "Ethnicity (%)", " Hispanic", " No info", " Non-hispnaic",
" Refused", " Unknown", "dx_age (mean (SD))"), `Stratified by site` = c("Phila",
"colorado", "nation", "Dup", "p", "test")))
When I converted tab to tap, the Dimnames in tab was gone.
tap <- as.data.table(tab)
dput(tap)
structure(list(Phila = c(" 1950", " ", " 207 (10.6) ",
" 288 (14.8) ", " 1455 (74.6) ", " ", " 95 ( 4.9) ",
" 0 ( 0.0) ", " 1823 (93.5) ", " 0 ( 0.0) ", " 32 ( 1.6) ",
"4721.83 (1322.96)"), colorado = c(" 553", " ", " 27 ( 4.9) ",
" 99 (17.9) ", " 427 (77.2) ", " ", " 68 (12.3) ",
" 0 ( 0.0) ", " 455 (82.3) ", " 0 ( 0.0) ", " 30 ( 5.4) ",
"4698.88 (1356.03)"), nation = c(" 813", " ", " 96 (11.8) ",
" 64 ( 7.9) ", " 653 (80.3) ", " ", " 8 ( 1.0) ",
" 0 ( 0.0) ", " 804 (98.9) ", " 0 ( 0.0) ", " 1 ( 0.1) ",
"4957.45 (1259.53)"), Dup = c(" 1243", " ", " 166 (13.4) ",
" 191 (15.4) ", " 886 (71.3) ", " ", " 129 (10.4) ",
" 0 ( 0.0) ", " 1098 (88.3) ", " 0 ( 0.0) ", " 16 ( 1.3) ",
"4861.85 (1221.35)"), p = c("", "<0.001", "", "", "", " NaN",
"", "", "", "", "", "<0.001"), test = c("", "", "", "", "", "",
"", "", "", "", "", "")), row.names = c(NA, -12L), class = c("data.table",
"data.frame"), .internal.selfref = <pointer: 0x0000000002621ef0>)
Did I do something wrong? or is there a better way to do the conversion, if not, how can I add this information back? Thanks a lot!
p.s
I also try change rownames of tap from data.frame but print out show X, X.1...which is an unintended results.
Thanks to everyone's tips, seems like there are no simple solution for this. My work around is to save rownames as permanent column and use regular expression to remove those lines starting with X within the column. Hope this will help those who came across similar issue.

Editable columns with calculations in Shiny DataTables

I have a datatable that is editable. The goal here is to have the user edit the GRPs/TRPs if they'd like. Upon editing that column, the Costs($) column will update accordingly. Here I am attempting to write some JS code and incorporate that into the datatable callback argument. Something isn't correct with the JS code and I can't figure out what it is. I'm very new the JS so bare with me.
# the math behind it
cost = OVERRIDE_CPP * GRPs/TRPs
df <- data.frame (Market = c("ALBANY-SCHENECTADY-TROY, NY", "ALBUQUERQUE-SANTA FE"),
Weeks = c(1, 1),
OVERRIDE_CPP = c(141.7, 188),
GRPs_TRPs = c(100L, 100L),
Cost = c(14170, 18800),
Impressions = c(2053.993,2053.993)
)
# Coster DataTable JS function
CosterTableJS <- function() {
return(
JS(
"var ok = true;",
"function onUpdate(updatedCell, updatedRow, oldValue) {",
" var column = updatedCell.index().column;",
" if(column === 4){",
" ok = false;",
" }else if(column === 3){",
" ok = true;",
" }",
"}",
"",
"// make the datatable",
"var format_datatable = function(d, rowIdx){",
" // footer callback to display the totals",
" var footerCallback = function(tfoot, data, start, end, display){",
" var api = this.api();",
"// update the Cost when the GRP/TRP's are changed",
" var col_trp_grp = api.column(3).data();",
" var col_override_cpp = api.column(2).data();",
" if(ok){",
" for(var i = 0; i < col_trp_grp.length; i++){",
" api.cell(i,4).data(parseFloat(col_trp_grp[i]) * parseFloat(col_override_cpp[i]));",
" }",
" }",
" Shiny.setInputValue('weeklyData:weeklyData', table.data().toArray());",
" }",
" var n = d.length - 1;",
" var id = 'table#';",
" 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,",
" 'footerCallback': footerCallback,",
" 'columnDefs': [",
" {targets: [0, 1, 2, 3, 4, 5]},",
" {targets: '_all', className: 'dt-center'}",
" ]",
" });",
" } else {",
" 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,",
" 'footerCallback': footerCallback,",
" 'columnDefs': [",
" {targets: -1, visible: false},",
" {targets: 0, orderable: false, className: 'details-control'},",
" {targets: '_all', className: 'dt-center'}",
" ]",
" }).column(0).nodes().to$().css({cursor: 'pointer'});",
" }",
"};"
)
)
}
coster_callback_js <- CosterTableJS()
rowNames <- FALSE
# Table
datatable(
df,
callback = coster_callback_js,
rownames = rowNames,
style = "bootstrap4",
extensions = 'Buttons',
options = list(
dom = "Bt",
columnDefs = list(
list(width = '300px', targets = 0)
),
lengthMenu = list(c(-1, 10, 20),
c("All", 10, 20))
)
)

Table with mixed formats - long and wide

I have this table in which every variable has a certain number of classes. I would like to know the amount of observations that are in every class. All my variables are organized in long format, but one - HINCFEL. I want to transform the variable into long format, as all the other variables, and add a column with the count of observation: so for example i would know how many observations do I have for GNDR is 1 and at the same time AGE is 1 and at the same time EDUC is 1 and at the same time ACTIVITY is 1 and at the same time HINCFEL is 1.
structure(c(" ", "\"CNTRY\"", "\"BE\" ", " ", " ",
" ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ",
"\"GNDR\"", "\"1\" ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", "\"AGE\"", "\"1\" ",
" ", " ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ", " ",
"\"2\" ", " ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ", " ",
" ", "\"3\" ", " ", " ", " ", " ", " ",
" ", " ", " ", " ", " ", " ", " ",
" ", " ", "\"4\" ", " ", " ", " ", " ",
" ", "\"EDUC\"", "\"1\" ", " ", " ", " ",
" ", "\"2\" ", " ", " ", " ", " ",
"\"3\" ", " ", " ", " ", " ", "\"1\" ",
" ", " ", " ", " ", "\"2\" ", " ",
" ", " ", " ", "\"3\" ", " ", " ",
" ", " ", "\"1\" ", " ", " ", " ",
" ", "\"2\" ", " ", " ", " ", " ",
"\"3\" ", " ", " ", " ", " ", "\"1\" ",
" ", " ", " ", " ", " ", "\"ACTIVITY\"",
"\"1\" ", "\"2\" ", "\"3\" ", "\"4\" ",
"\"5\" ", "\"1\" ", "\"2\" ", "\"3\" ",
"\"4\" ", "\"5\" ", "\"1\" ", "\"2\" ",
"\"3\" ", "\"4\" ", "\"5\" ", "\"1\" ",
"\"2\" ", "\"3\" ", "\"4\" ", "\"5\" ",
"\"1\" ", "\"2\" ", "\"3\" ", "\"4\" ",
"\"5\" ", "\"1\" ", "\"2\" ", "\"3\" ",
"\"4\" ", "\"5\" ", "\"1\" ", "\"2\" ",
"\"3\" ", "\"4\" ", "\"5\" ", "\"1\" ",
"\"2\" ", "\"3\" ", "\"4\" ", "\"5\" ",
"\"1\" ", "\"2\" ", "\"3\" ", "\"4\" ",
"\"5\" ", "\"1\" ", "\"2\" ", "\"3\" ",
"\"4\" ", "\"5\" ", "\"HINCFEL\"", " ", " ",
" ", " ", " ", " ", " ",
" ", " ", " ", " ", " ",
" ", " ", " ", " ", " ",
" ", " ", " ", " ", " ",
" ", " ", " ", " ", " ",
" ", " ", " ", " ", " ",
" ", " ", " ", " ", " ",
" ", " ", " ", " ", " ",
" ", " ", " ", " ", " ",
" ", " ", " ", " ", "\"1\"",
" ", " 4", " 0", " 0", " 25", " 1", " 10", " 1", " 0",
" 12", " 3", " 28", " 1", " 0", " 2", " 1", " 7", " 0",
" 0", " 0", " 1", " 27", " 0", " 0", " 0", " 0", " 41",
" 1", " 0", " 0", " 1", " 8", " 0", " 1", " 0", " 2",
" 34", " 0", " 2", " 0", " 2", " 33", " 0", " 1", " 0",
" 1", " 1", " 0", " 13", " 0", " 3", "\"2\"", " ", " 7",
" 1", " 0", " 13", " 2", " 17", " 0", " 0", " 9", " 5",
" 15", " 0", " 0", " 3", " 0", " 8", " 0", " 0", " 0",
" 0", " 44", " 1", " 0", " 0", " 1", " 29", " 0", " 0",
" 0", " 1", " 24", " 1", " 3", " 0", " 5", " 34", " 0",
" 7", " 0", " 0", " 16", " 1", " 1", " 0", " 4", " 1",
" 1", " 41", " 0", " 1", "\"3\"", " ", " 1", " 1", " 0",
" 5", " 2", " 5", " 4", " 0", " 2", " 0", " 1", " 2",
" 0", " 0", " 1", " 14", " 2", " 0", " 1", " 1", " 19",
" 5", " 0", " 0", " 3", " 4", " 1", " 0", " 1", " 0",
" 8", " 2", " 2", " 0", " 6", " 9", " 0", " 2", " 0",
" 3", " 5", " 0", " 0", " 0", " 1", " 2", " 0", " 19",
" 0", " 4", "\"4\"", " ", " 2", " 0", " 0", " 1", " 0",
" 0", " 0", " 0", " 1", " 0", " 0", " 0", " 0", " 0",
" 0", " 1", " 4", " 0", " 0", " 0", " 1", " 2", " 0",
" 0", " 0", " 0", " 0", " 0", " 1", " 0", " 3", " 0",
" 0", " 0", " 1", " 0", " 1", " 0", " 0", " 3", " 0",
" 2", " 0", " 0", " 0", " 0", " 2", " 1", " 0", " 1"
), .Dim = c(52L, 10L), .Dimnames = list(c("", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", ""),
c("", "", "", "", "", "", "", "", "", "")), class = "noquote")

Resources