Javascript 为R DT编写代码时出现问题,该代码总结了多个研究中的结果,其中包含可折叠的子行
我试图制作一个交互式表格,总结在多个研究中测试的结果的顶部结果,我还希望用户通过子行访问更详细的结果。主表中仅显示p值最小的“顶部”模型 现在我将相关结果分为两个数据帧:1。仅限最高成绩,以及2。详细结果。我正在合并这些,并根据我想要显示的最重要的结果进行嵌套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
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('⊕',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('⊕');
} else {
row.child(format(row.data())).show();
td.html('⊖');
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"],["⊕","⊕"],["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('⊕');\n } else {\n row.child(format(row.data())).show();\n td.html('⊖');\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('⊕',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('⊕');
} else {
row.child(format(row.data())).show();
td.html('⊖');
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('⊕',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('⊕');
} else {
row.child(format(row.data())).show();
td.html('⊖');
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('⊕',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('⊕');
} else {
row.child(format(row.data())).show();
td.html('⊖');
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`