Javascript 为R DT编写代码时出现问题,该代码总结了多个研究中的结果,其中包含可折叠的子行

Javascript 为R DT编写代码时出现问题,该代码总结了多个研究中的结果,其中包含可折叠的子行,javascript,r,r-markdown,dt,Javascript,R,R Markdown,Dt,我试图制作一个交互式表格,总结在多个研究中测试的结果的顶部结果,我还希望用户通过子行访问更详细的结果。主表中仅显示p值最小的“顶部”模型 现在我将相关结果分为两个数据帧:1。仅限最高成绩,以及2。详细结果。我正在合并这些,并根据我想要显示的最重要的结果进行嵌套 library(DT) library(tidyr) library(dplyr) library(tibble) # == Create dataframe with results to summarize allresults

我试图制作一个交互式表格,总结在多个研究中测试的结果的顶部结果,我还希望用户通过子行访问更详细的结果。主表中仅显示p值最小的“顶部”模型

现在我将相关结果分为两个数据帧:1。仅限最高成绩,以及2。详细结果。我正在合并这些,并根据我想要显示的最重要的结果进行嵌套

library(DT)
library(tidyr)
library(dplyr)
library(tibble)

# == Create dataframe with results to summarize


allresults <- list(c("HeartAttack", 1e-6, 0.05, 0.005, "study1", "heartAttack_v1", "ageSex", 1e-6), 
                   c("HeartAttack", 1e-6, 0.05, 0.005, "study1", "heartAttack_v2", "ageSexBmi", 0.001), 
                   c("HeartAttack", 1e-6, 0.05, 0.005, "study2", "heartAttack_v1", "ageSex", 0.05), 
                   c("HeartAttack", 1e-6, 0.05, 0.005, "study2", "heartAttack_v2", "ageSexBmi", "0.2"), 
                   c("HeartAttack", 1e-6, 0.05, 0.005, "study3", "heartAttack_v1", "ageSex", "0.005"), 
                   c( "Cancer",  0.05, 0.01, 0.002, "study1", "cancer_v1", "ageSex", 0.6), 
                   c( "Cancer",  0.05, 0.01, 0.002, "study1", "cancer_v2", "ageSex", 0.05), 
                   c("Cancer",  0.05, 0.01, 0.002, "study2", "cancer_v1", "ageSexBmi", 0.2), 
                   c("Cancer",  0.05, 0.01, 0.002, "study2", "cancer_v2", "ageSex", 0.01), 
                   c("Cancer",  0.05, 0.01, 0.002, "study3", "cancer_v1", "ageSexBmi", 0.002))

df <- as.data.frame(t(as.data.frame(allresults)))
colnames(df) <- c("outcome.bestOf", "study1.bestOf", "study2.bestOf", "study3.bestOf", "studyName", "outcome", "model", "pvalue")
rownames(df)<-NULL



# == Collapse to display top-result table, one row per outcome
nest_fields <- c("outcome.bestOf", "study1.bestOf", "study2.bestOf", "study3.bestOf") 
dt <- df %>%
  nest(-nest_fields)

# == Add (+) column
data <- dt %>% {bind_cols(data_frame(' ' = rep('&oplus;',nrow(.))),.)}

# == Get dynamic info and strings
# == code via: https://github.com/rstudio/shiny-examples/issues/9

nested_columns         <- which(sapply(data,class)=="list") %>% setNames(NULL)
not_nested_columns     <- which(!(seq_along(data) %in% c(1,nested_columns)))
not_nested_columns_str <- not_nested_columns %>% paste(collapse="] + '_' + d[") %>% paste0("d[",.,"]")

# == The callback
# == Turn rows into child rows and remove from parent
callback <- paste0("
                   table.column(1).nodes().to$().css({cursor: 'pointer'});

                   // Format data object (the nested table) into another table
                   var format = function(d) {
                   if(d != null){ 
                   var result = ('<table id=\"child_' + ",not_nested_columns_str," + '\">').replace('.','_') + '<thead><tr>'
                   for (var col in d[",nested_columns,"]){
                   result += '<th>' + col + '</th>'
                   }
                   result += '</tr></thead></table>'
                   return result
                   }else{
                   return '';
                   }
                   }

                   var format_datatable = function(d) {
                   var dataset = [];
                   for (i = 0; i < + d[",nested_columns,"]['cohort'].length; i++) {
                   var datarow = [];
                   for (var col in d[",nested_columns,"]){
                   datarow.push(d[",nested_columns,"][col][i])
                   }
                   dataset.push(datarow)
                   }
                   var subtable = $(('table#child_' + ",not_nested_columns_str,").replace('.','_')).DataTable({
                   'data': dataset,
                   'autoWidth': true, 
                   'deferRender': true, 
                   'info': false, 
                   'lengthChange': false, 
                   'ordering': true, 
                   'paging': false, 
                   'scrollX': false, 
                   'scrollY': false, 
                   'searching': false 
                   });
                   };

                   table.on('click', 'td.details-control', function() {
                   var td = $(this), row = table.row(td.closest('tr'));
                   if (row.child.isShown()) {
                   row.child.hide();
                   td.html('&oplus;');
                   } else {
                   row.child(format(row.data())).show();
                   td.html('&CircleMinus;');
                   format_datatable(row.data())
                   }
                   });"
                  )


# == the Display DT
datatable(
  data,
  escape = FALSE,
  options = list(
    columnDefs = list(
      list(visible = FALSE, targets = c(0,nested_columns) ), # Hide row numbers and nested columns
      list(orderable = FALSE, className = 'details-control', targets = 1) # turn first column into control column
    )
  ),
  callback = JS(callback)
)
库(DT)
图书馆(tidyr)
图书馆(dplyr)
图书馆(tibble)
#==使用要汇总的结果创建数据帧
allresults数据[数据$outcome.bestOf==“癌症”,“数据”][[1]]
[[1]]
#一个tibble:5x4
studyName结果模型pvalue
1研究1癌症1年龄性别0.6
2研究1癌症2年龄性别0.05
3研究2癌症1年龄性别BMI 0.2
4研究2癌症2年龄性别0.01
5研究3癌症1年龄性别BMI 0.002
***编辑**** 下面是Chrome的inspect元素选项中的html:


    <html><head>
    <meta charset="utf-8">
    <script src="lib/htmlwidgets-1.3/htmlwidgets.js"></script>
    <script src="lib/jquery-1.12.4/jquery.min.js"></script>
    <link href="lib/datatables-css-0.0.0/datatables-crosstalk.css" rel="stylesheet">
    <script src="lib/datatables-binding-0.5/datatables.js"></script>
    <link href="lib/dt-core-1.10.16/css/jquery.dataTables.min.css" rel="stylesheet">
    <link href="lib/dt-core-1.10.16/css/jquery.dataTables.extra.css" rel="stylesheet">
    <script src="lib/dt-core-1.10.16/js/jquery.dataTables.min.js"></script>
    <link href="lib/crosstalk-1.0.0/css/crosstalk.css" rel="stylesheet">
    <script src="lib/crosstalk-1.0.0/js/crosstalk.min.js"></script>

    </head>
    <body style="background-color: white; margin: 0px; padding: 40px;">
    <div id="htmlwidget_container">
      <div id="htmlwidget-3a36880ad35572a39f25" style="width:960px;height:500px;" class="datatables html-widget html-widget-static-bound"><div id="DataTables_Table_0_wrapper" class="dataTables_wrapper no-footer"><div class="dataTables_length" id="DataTables_Table_0_length"><label>Show <select name="DataTables_Table_0_length" aria-controls="DataTables_Table_0" class=""><option value="10">10</option><option value="25">25</option><option value="50">50</option><option value="100">100</option></select> entries</label></div><div id="DataTables_Table_0_filter" class="dataTables_filter"><label>Search:<input type="search" class="" placeholder="" aria-controls="DataTables_Table_0"></label></div><table class="display dataTable no-footer" id="DataTables_Table_0" role="grid" aria-describedby="DataTables_Table_0_info">
      <thead>
        <tr role="row"><th class="details-control sorting_disabled" rowspan="1" colspan="1" aria-label=" "> </th><th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="outcome.bestOf: activate to sort column ascending">outcome.bestOf</th><th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="study1.bestOf: activate to sort column ascending">study1.bestOf</th><th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="study2.bestOf: activate to sort column ascending">study2.bestOf</th><th class="sorting" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="study3.bestOf: activate to sort column ascending">study3.bestOf</th></tr>
      </thead>
    <tbody><tr role="row" class="odd"><td class=" details-control" style="cursor: pointer;">⊕</td><td>HeartAttack</td><td>1e-06</td><td>0.05</td><td>0.005</td></tr><tr role="row" class="even"><td class=" details-control" style="cursor: pointer;">⊕</td><td>Cancer</td><td>0.05</td><td>0.01</td><td>0.002</td></tr></tbody></table><div class="dataTables_info" id="DataTables_Table_0_info" role="status" aria-live="polite">Showing 1 to 2 of 2 entries</div><div class="dataTables_paginate paging_simple_numbers" id="DataTables_Table_0_paginate"><a class="paginate_button previous disabled" aria-controls="DataTables_Table_0" data-dt-idx="0" tabindex="0" id="DataTables_Table_0_previous">Previous</a><span><a class="paginate_button current" aria-controls="DataTables_Table_0" data-dt-idx="1" tabindex="0">1</a></span><a class="paginate_button next disabled" aria-controls="DataTables_Table_0" data-dt-idx="2" tabindex="0" id="DataTables_Table_0_next">Next</a></div></div></div>
    </div>
    <script type="application/json" data-for="htmlwidget-3a36880ad35572a39f25">{"x":{"filter":"none","data":[["1","2"],["&oplus;","&oplus;"],["HeartAttack","Cancer"],["1e-06","0.05"],["0.05","0.01"],["0.005","0.002"],[{"studyName":["study1","study1","study2","study2","study3"],"outcome":["heartAttack_v1","heartAttack_v2","heartAttack_v1","heartAttack_v2","heartAttack_v1"],"model":["ageSex","ageSexBmi","ageSex","ageSexBmi","ageSex"],"pvalue":["1e-06","0.001","0.05","0.2","0.005"]},{"studyName":["study1","study1","study2","study2","study3"],"outcome":["cancer_v1","cancer_v2","cancer_v1","cancer_v2","cancer_v1"],"model":["ageSex","ageSex","ageSexBmi","ageSex","ageSexBmi"],"pvalue":["0.6","0.05","0.2","0.01","0.002"]}]],"container":"<table class=\"display\">\n  <thead>\n    <tr>\n      <th> <\/th>\n      <th> <\/th>\n      <th>outcome.bestOf<\/th>\n      <th>study1.bestOf<\/th>\n      <th>study2.bestOf<\/th>\n      <th>study3.bestOf<\/th>\n      <th>data<\/th>\n    <\/tr>\n  <\/thead>\n<\/table>","options":{"columnDefs":[{"visible":false,"targets":[0,6]},{"orderable":false,"className":"details-control","targets":1},{"orderable":false,"targets":0}],"order":[],"autoWidth":false,"orderClasses":false},"callback":"function(table) {\n\n                   table.column(1).nodes().to$().css({cursor: 'pointer'});\n                   \n                   // Format data object (the nested table) into another table\n                   var format = function(d) {\n                   if(d != null){ \n                   var result = ('<table id=\"child_' + d[2] + '_' + d[3] + '_' + d[4] + '_' + d[5] + '\">').replace('.','_') + '<thead><tr>'\n                   for (var col in d[6]){\n                   result += '<th>' + col + '<\/th>'\n                   }\n                   result += '<\/tr><\/thead><\/table>'\n                   return result\n                   }else{\n                   return '';\n                   }\n                   }\n                   \n                   var format_datatable = function(d) {\n                   var dataset = [];\n                   for (i = 0; i < + d[6]['cohort'].length; i++) {\n                   var datarow = [];\n                   for (var col in d[6]){\n                   datarow.push(d[6][col][i])\n                   }\n                   dataset.push(datarow)\n                   }\n                   var subtable = $(('table#child_' + d[2] + '_' + d[3] + '_' + d[4] + '_' + d[5]).replace('.','_')).DataTable({\n                   'data': dataset,\n                   'autoWidth': true, \n                   'deferRender': true, \n                   'info': false, \n                   'lengthChange': false, \n                   'ordering': true, \n                   'paging': false, \n                   'scrollX': false, \n                   'scrollY': false, \n                   'searching': false \n                   });\n                   };\n                   \n                   table.on('click', 'td.details-control', function() {\n                   var td = $(this), row = table.row(td.closest('tr'));\n                   if (row.child.isShown()) {\n                   row.child.hide();\n                   td.html('&oplus;');\n                   } else {\n                   row.child(format(row.data())).show();\n                   td.html('&CircleMinus;');\n                   format_datatable(row.data())\n                   }\n                   });\n}"},"evals":["callback"],"jsHooks":[]}</script>
    <script type="application/htmlwidget-sizing" data-for="htmlwidget-3a36880ad35572a39f25">{"viewer":{"width":450,"height":350,"padding":15,"fill":true},"browser":{"width":960,"height":500,"padding":40,"fill":false}}</script>


    </body></html>


显示102550100 entriesSearch:
结果:最佳研究1.最佳研究2.最佳研究3.最佳研究
⊕HeartAttack1e-060.050.005⊕Cancer0.050.010.0022显示2个中心中的1到2个,前一个1下一个
{“x”:{“过滤器”:“无”,“数据”:[“1”,“2”],[“&oplus;”,“&oplus;”],[“心脏病发作”,“癌症”],[“1e-06”,“0.05”],[“0.05”,“0.01”],[“0.005”,“0.002”],[{“研究名称”:[“研究1”,“研究1”,“研究2”,“研究2”,“研究2”,“研究3”],“结果”:[“心脏病发作v1”,“心脏病发作v2”,“心脏病发作v1”,“心脏病v2”,“心脏病发作模型”,“性别”,“BMI”],“年龄性别”],“pvalue”:[“1e-06”,“0.001”,“0.05”,“0.2”,“0.005”],{“studyName”:[“study1”,“study1”,“study2”,“study2”,“study2”,“study3”],“结果”:[“cancer_v1”,“cancer_v2”,“cancer_v1”,“cancer_v2”,“cancer_v1”],“model”:[“ageSex”,“ageSex”,“ageSex体重指数”,“ageSex体重指数”,“pvalue”],“0.6”,“0.05”,“0.2”,“0.01”,“0.002”],“pvalue”:\n\n\n\n\n结果。bestOf\n study1.bestOf\n study2.bestOf\n study3.bestOf\n数据\n\n\n,“选项”:{“columnDefs”:[{“visible”:false,“targets”:[0,6]},{“orderable”:false,“className”:“details control”,“targets”:1},{“orderable”:false,“targets”:0},“OrderClass”:[],“autoWidth”:false,”回调“:“function(table){\n\n table.column(1).nodes().to$().css({cursor:'pointer'});\n\n//将数据对象(嵌套的表)格式化为另一个表\n var Format=function(d){\n if(d!=null){\n var result=('')。替换('.','''.''.'''.\u')+''\n for(d[6]中的var col]){\n result+='+col+''\n}\n result+='\n return result\n}否则{\n return';\n}\n}\n\n var format_datatable=function(d){\n var dataset=[];\n for(i=0;i<+d[6]['court'].length;i++){\n var datarow=[];\n for(d[6]中的var col.{\n datarow.push(d[6][col i])\n}\n dataset.push(datarow)\n}\n var subtable=$('table#child ud+d[2]+''.+d[3]+'.+d[4]+'.+d[5])。replace('.',''.''''.')。DataTable({\n“数据”:数据集,\n“自动宽度”:真,\n“延迟渲染”:真,\n“信息”:假,\n“长度更改”:假,\n“排序”:真,\n“分页”:假,\n“滚动X”:假,\n“滚动”:false、\n“搜索”:false\n});\n};\n\n table.on('click','td.details control',function(){\n var td=$(this),row=table.row(td.nestest('tr');\n if(row.child.isShown()){\n row.child.hide();\n td.html('&oplus;');\n}else{\n row.child(format(row.data()).show();\n td.html('&CircleMinus;');\n format_datatable(row.data())\n}\n},“evals”:[“callback”],“jsHooks”:[]}
{“查看器”:{“宽度”:450,“高度”:350,“填充”:15,“填充”:true},“浏览器”:{“宽度”:960,“高度”:500,“填充”:40,“填充”:false}
****编辑2****并进行Stéphane Laurent建议的更改

allresults <- list(c("HeartAttack", 1e-6, 0.05, 0.005, "study1", "heartAttack_v1", "ageSex", 1e-6), 
                   c("HeartAttack", 1e-6, 0.05, 0.005, "study1", "heartAttack_v2", "ageSexBmi", 0.001), 
                   c("HeartAttack", 1e-6, 0.05, 0.005, "study2", "heartAttack_v1", "ageSex", 0.05), 
                   c("HeartAttack", 1e-6, 0.05, 0.005, "study2", "heartAttack_v2", "ageSexBmi", "0.2"), 
                   c("HeartAttack", 1e-6, 0.05, 0.005, "study3", "heartAttack_v1", "ageSex", "0.005"), 
                   c( "Cancer",  0.05, 0.01, 0.002, "study1", "cancer_v1", "ageSex", 0.6), 
                   c( "Cancer",  0.05, 0.01, 0.002, "study1", "cancer_v2", "ageSex", 0.05), 
                   c("Cancer",  0.05, 0.01, 0.002, "study2", "cancer_v1", "ageSexBmi", 0.2), 
                   c("Cancer",  0.05, 0.01, 0.002, "study2", "cancer_v2", "ageSex", 0.01), 
                   c("Cancer",  0.05, 0.01, 0.002, "study3", "cancer_v1", "ageSexBmi", 0.002))

df <- as.data.frame(t(as.data.frame(allresults)))
colnames(df) <- c("outcome.bestOf", "study1.bestOf", "study2.bestOf", "study3.bestOf", "studyName", "outcome", "model", "pvalue")
rownames(df)<-NULL



# == Collapse to display top-result table, one row per outcome
nest_fields <- c("outcome.bestOf", "study1.bestOf", "study2.bestOf", "study3.bestOf") 
dt <- df %>%
  nest(-nest_fields)

# == Add (+) column
data <- dt %>% {bind_cols(data_frame(' ' = rep('&oplus;',nrow(.))),.)}

# == Get dynamic info and strings
# == code via: https://github.com/rstudio/shiny-examples/issues/9

nested_columns         <- which(sapply(data,class)=="list") %>% setNames(NULL)
not_nested_columns     <- which(!(seq_along(data) %in% c(1,nested_columns)))
not_nested_columns_str <- not_nested_columns %>% paste(collapse="] + '_' + d[") %>% paste0("d[",.,"]")

# == The callback
# == Turn rows into child rows and remove from parent
callback <- paste0("
                   table.column(1).nodes().to$().css({cursor: 'pointer'});

                   // Format data object (the nested table) into another table
                   var format = function(d) {
                   if(d != null){ 
                   var result = ('<table id=\"child_' + ",not_nested_columns_str," + '\">').replace('/\\./g','_') + '<thead><tr>'
                   for (var col in d[",nested_columns,"]){
                   result += '<th>' + col + '</th>'
                   }
                   result += '</tr></thead></table>'
                   return result
                   }else{
                   return '';
                   }
                   }

                   var format_datatable = function(d) {
                   var dataset = [];
                   for (i = 0; i < + d[",nested_columns,"]['studyName'].length; i++) {
                   var datarow = [];
                   for (var col in d[",nested_columns,"]){
                   datarow.push(d[",nested_columns,"][col][i])
                   }
                   dataset.push(datarow)
                   }
                   var subtable = $(('table#child_' + ",not_nested_columns_str,").replace('/\\./g','_') ).DataTable({
                   'data': dataset,
                   'autoWidth': true, 
                   'deferRender': true, 
                   'info': false, 
                   'lengthChange': false, 
                   'ordering': true, 
                   'paging': false, 
                   'scrollX': false, 
                   'scrollY': false, 
                   'searching': false 
                   });
                   };

                   table.on('click', 'td.details-control', function() {
                   var td = $(this), row = table.row(td.closest('tr'));
                   if (row.child.isShown()) {
                   row.child.hide();
                   td.html('&oplus;');
                   } else {
                   row.child(format(row.data())).show();
                   td.html('&CircleMinus;');
                   format_datatable(row.data())
                   }
                   });"
                  )


# == the Display DT
datatable(
  data,
  escape = FALSE,
  options = list(
    columnDefs = list(
      list(visible = FALSE, targets = c(0,nested_columns) ), # Hide row numbers and nested columns
      list(orderable = FALSE, className = 'details-control', targets = 1) # turn first column into control column
    )
  ),
  callback = JS(callback)
)

所有结果有两个问题

d[",nested_columns,"]['cohort'].length
没有
队列
列。替换为

d[",nested_columns,"]['studyName'].length
另一个问题是用下划线替换点:

var result = ('<table id=\"child_' + ",not_nested_columns_str," + '\">').replace('.','_') + '<thead><tr>'

完整代码:

library(DT)
library(tidyr)
library(dplyr)
library(tibble)

# == Create dataframe with results to summarize
allresults <- list(c("HeartAttack", 1e-6, 0.05, 0.005, "study1", "heartAttack_v1", "ageSex", 1e-6), 
                   c("HeartAttack", 1e-6, 0.05, 0.005, "study1", "heartAttack_v2", "ageSexBmi", 0.001), 
                   c("HeartAttack", 1e-6, 0.05, 0.005, "study2", "heartAttack_v1", "ageSex", 0.05), 
                   c("HeartAttack", 1e-6, 0.05, 0.005, "study2", "heartAttack_v2", "ageSexBmi", "0.2"), 
                   c("HeartAttack", 1e-6, 0.05, 0.005, "study3", "heartAttack_v1", "ageSex", "0.005"), 
                   c( "Cancer",  0.05, 0.01, 0.002, "study1", "cancer_v1", "ageSex", 0.6), 
                   c( "Cancer",  0.05, 0.01, 0.002, "study1", "cancer_v2", "ageSex", 0.05), 
                   c("Cancer",  0.05, 0.01, 0.002, "study2", "cancer_v1", "ageSexBmi", 0.2), 
                   c("Cancer",  0.05, 0.01, 0.002, "study2", "cancer_v2", "ageSex", 0.01), 
                   c("Cancer",  0.05, 0.01, 0.002, "study3", "cancer_v1", "ageSexBmi", 0.002))

df <- as.data.frame(t(as.data.frame(allresults)))
colnames(df) <- c("outcome.bestOf", "study1.bestOf", "study2.bestOf", "study3.bestOf", "studyName", "outcome", "model", "pvalue")
rownames(df)<-NULL

# == Collapse to display top-result table, one row per outcome
nest_fields <- c("outcome.bestOf", "study1.bestOf", "study2.bestOf", "study3.bestOf") 
dt <- df %>%
  nest(-nest_fields)

# == Add (+) column
data <- dt %>% {bind_cols(data_frame(' ' = rep('&oplus;',nrow(.))),.)}

# == Get dynamic info and strings
# == code via: https://github.com/rstudio/shiny-examples/issues/9

nested_columns         <- which(sapply(data,class)=="list") %>% setNames(NULL)
not_nested_columns     <- which(!(seq_along(data) %in% c(1,nested_columns)))
not_nested_columns_str <- not_nested_columns %>% paste(collapse="] + '_' + d[") %>% paste0("d[",.,"]")

# == The callback
# == Turn rows into child rows and remove from parent
callback <- paste0("
                   table.column(1).nodes().to$().css({cursor: 'pointer'});

                   // Format data object (the nested table) into another table
                   var format = function(d) {
                   if(d != null){ 
                   var result = ('<table id=\"child_' + ",not_nested_columns_str," + '\">').replace(/\\./g,'_') + '<thead><tr>'
                   for (var col in d[",nested_columns,"]){
                   result += '<th>' + col + '</th>'
                   }
                   result += '</tr></thead></table>'
                   return result
                   }else{
                   return '';
                   }
                   }

                   var format_datatable = function(d) {
                   var dataset = [];
                   for (var i = 0; i < + d[",nested_columns,"]['studyName'].length; i++) {
                   var datarow = [];
                   for (var col in d[",nested_columns,"]){
                   datarow.push(d[",nested_columns,"][col][i])
                   }
                   dataset.push(datarow)
                   }
                   var subtable = $(('table#child_' + ",not_nested_columns_str,").replace(/\\./g,'_')).DataTable({
                   'data': dataset,
                   'autoWidth': true, 
                   'deferRender': true, 
                   'info': false, 
                   'lengthChange': false, 
                   'ordering': true, 
                   'paging': false, 
                   'scrollX': false, 
                   'scrollY': false, 
                   'searching': false 
                   });
                   };

                   table.on('click', 'td.details-control', function() {
                   var td = $(this), row = table.row(td.closest('tr'));
                   if (row.child.isShown()) {
                   row.child.hide();
                   td.html('&oplus;');
                   } else {
                   row.child(format(row.data())).show();
                   td.html('&CircleMinus;');
                   format_datatable(row.data())
                   }
                   });"
                  )


# == the Display DT
datatable(
  data,
  escape = FALSE,
  options = list(
    columnDefs = list(
      list(visible = FALSE, targets = c(0,nested_columns) ), # Hide row numbers and nested columns
      list(orderable = FALSE, className = 'details-control', targets = 1) # turn first column into control column
    )
  ),
  callback = JS(callback)
)
库(DT)
图书馆(tidyr)
图书馆(dplyr)
图书馆(tibble)
#==使用要汇总的结果创建数据帧
所有结果都是未来的证明
基于@StéphaneLaurent的出色回答,以下是一些变化,使其成为2020年的证明:

  • 现在所有输入都必须以
    nest()命名
    ,因此将
    nest(-nest\u字段)
    替换为
    nest(数据=(-nest\u字段))
  • data.frame()
    给出一个错误,应在此行中替换为
    tibble()
    data%{bind_cols(data.frame('=rep('&oplus;',nrow(),),)}
  • nested\u columns%setNames(NULL)
    不再工作,因为出于某种原因,嵌套的TIBLE类不再是
    list
    ,而是两个类:
    “vctrs\u list\u of”
    “vctrs\u vctr”
    。我们需要添加一个额外的
    sapply()
    处理双类,如:
    嵌套列%setNames(NULL)

  • 边缘情况(FWIW) 在
    var result = ('<table id=\"child_' + ",not_nested_columns_str," + '\">').replace('/\\./g','_') + '<thead><tr>'
    
    var subtable = $(('table#child_' + ",not_nested_columns_str,").replace('.','_')).DataTable({
    
    library(DT)
    library(tidyr)
    library(dplyr)
    library(tibble)
    
    # == Create dataframe with results to summarize
    allresults <- list(c("HeartAttack", 1e-6, 0.05, 0.005, "study1", "heartAttack_v1", "ageSex", 1e-6), 
                       c("HeartAttack", 1e-6, 0.05, 0.005, "study1", "heartAttack_v2", "ageSexBmi", 0.001), 
                       c("HeartAttack", 1e-6, 0.05, 0.005, "study2", "heartAttack_v1", "ageSex", 0.05), 
                       c("HeartAttack", 1e-6, 0.05, 0.005, "study2", "heartAttack_v2", "ageSexBmi", "0.2"), 
                       c("HeartAttack", 1e-6, 0.05, 0.005, "study3", "heartAttack_v1", "ageSex", "0.005"), 
                       c( "Cancer",  0.05, 0.01, 0.002, "study1", "cancer_v1", "ageSex", 0.6), 
                       c( "Cancer",  0.05, 0.01, 0.002, "study1", "cancer_v2", "ageSex", 0.05), 
                       c("Cancer",  0.05, 0.01, 0.002, "study2", "cancer_v1", "ageSexBmi", 0.2), 
                       c("Cancer",  0.05, 0.01, 0.002, "study2", "cancer_v2", "ageSex", 0.01), 
                       c("Cancer",  0.05, 0.01, 0.002, "study3", "cancer_v1", "ageSexBmi", 0.002))
    
    df <- as.data.frame(t(as.data.frame(allresults)))
    colnames(df) <- c("outcome.bestOf", "study1.bestOf", "study2.bestOf", "study3.bestOf", "studyName", "outcome", "model", "pvalue")
    rownames(df)<-NULL
    
    # == Collapse to display top-result table, one row per outcome
    nest_fields <- c("outcome.bestOf", "study1.bestOf", "study2.bestOf", "study3.bestOf") 
    dt <- df %>%
      nest(-nest_fields)
    
    # == Add (+) column
    data <- dt %>% {bind_cols(data_frame(' ' = rep('&oplus;',nrow(.))),.)}
    
    # == Get dynamic info and strings
    # == code via: https://github.com/rstudio/shiny-examples/issues/9
    
    nested_columns         <- which(sapply(data,class)=="list") %>% setNames(NULL)
    not_nested_columns     <- which(!(seq_along(data) %in% c(1,nested_columns)))
    not_nested_columns_str <- not_nested_columns %>% paste(collapse="] + '_' + d[") %>% paste0("d[",.,"]")
    
    # == The callback
    # == Turn rows into child rows and remove from parent
    callback <- paste0("
                       table.column(1).nodes().to$().css({cursor: 'pointer'});
    
                       // Format data object (the nested table) into another table
                       var format = function(d) {
                       if(d != null){ 
                       var result = ('<table id=\"child_' + ",not_nested_columns_str," + '\">').replace(/\\./g,'_') + '<thead><tr>'
                       for (var col in d[",nested_columns,"]){
                       result += '<th>' + col + '</th>'
                       }
                       result += '</tr></thead></table>'
                       return result
                       }else{
                       return '';
                       }
                       }
    
                       var format_datatable = function(d) {
                       var dataset = [];
                       for (var i = 0; i < + d[",nested_columns,"]['studyName'].length; i++) {
                       var datarow = [];
                       for (var col in d[",nested_columns,"]){
                       datarow.push(d[",nested_columns,"][col][i])
                       }
                       dataset.push(datarow)
                       }
                       var subtable = $(('table#child_' + ",not_nested_columns_str,").replace(/\\./g,'_')).DataTable({
                       'data': dataset,
                       'autoWidth': true, 
                       'deferRender': true, 
                       'info': false, 
                       'lengthChange': false, 
                       'ordering': true, 
                       'paging': false, 
                       'scrollX': false, 
                       'scrollY': false, 
                       'searching': false 
                       });
                       };
    
                       table.on('click', 'td.details-control', function() {
                       var td = $(this), row = table.row(td.closest('tr'));
                       if (row.child.isShown()) {
                       row.child.hide();
                       td.html('&oplus;');
                       } else {
                       row.child(format(row.data())).show();
                       td.html('&CircleMinus;');
                       format_datatable(row.data())
                       }
                       });"
                      )
    
    
    # == the Display DT
    datatable(
      data,
      escape = FALSE,
      options = list(
        columnDefs = list(
          list(visible = FALSE, targets = c(0,nested_columns) ), # Hide row numbers and nested columns
          list(orderable = FALSE, className = 'details-control', targets = 1) # turn first column into control column
        )
      ),
      callback = JS(callback)
    )
    
    "var result = ('<table id=\"child_' + ",not_nested_columns_str," + '\">').replace(/\\./g,'_') + '<thead><tr>'"
    
    "var result = ('<table id=\"child_' + d[",id_column,"] + '\">') + '<thead><tr>'"
    
    "var subtable = $(('table#child_' + d[",id_column,"])).DataTable({"
    
    list(visible = FALSE, targets = c(0,id_column,nested_columns) ), # Hide row numbers and nested columns`