Machine Learning - Diagnostic - Analysis Report
This feature can be used to obtain diagnostic information, referred to as the Grow Settings and Analysis Report, for a segmentation/tree output from Latent Class Analysis, Mixed-Mode Cluster Analysis, or Mixed-Mode Tree.
Usage
- First select any or multiple output(s) from a Mixed-Mode Tree, Mixed-Mode Cluster Analysis, and/or a Latent Class Analysis.
- Run Anything > Advanced Analysis > Cluster > Diagnostic > Analysis Report to obtain the grow settings and analysis report for each selected segmentation output.
Example
Below are the results of running a Latent Class Analysis using several variable sets from a survey examining respondents' preferences for different types of cola.
After selecting the output and runnning Anything > Advanced Analysis > Cluster > Diagnostic > Analysis Report, the following report is obtained.
Technical details
If you modify any of the input data to your tree or update/rerun your analysis, you will need to rerun this feature to obtain the new analysis report. The output containing the report will show an error informing you of this.
How to apply this QScript
- Start typing the name of the QScript into the Search features and data box in the top right of the Q window.
- Click on the QScript when it appears in the QScripts and Rules section of the search results.
OR
- Select Automate > Browse Online Library.
- Select this QScript from the list.
Customizing the QScript
This QScript is written in JavaScript and can be customized by copying and modifying the JavaScript.
Customizing QScripts in Q4.11 and more recent versions
- Start typing the name of the QScript into the Search features and data box in the top right of the Q window.
- Hover your mouse over the QScript when it appears in the QScripts and Rules section of the search results.
- Press Edit a Copy (bottom-left corner of the preview).
- Modify the JavaScript (see QScripts for more detail on this).
- Either:
- Run the QScript, by pressing the blue triangle button.
- Save the QScript and run it at a later time, using Automate > Run QScript (Macro) from File.
Customizing QScripts in older versions
JavaScript
includeWeb("QScript Functions to Generate Outputs");
includeWeb("QScript R Output Functions");
function AddAnalysisReportWidgets() {
let selected = project.report.selectedRaw();
let trees = selected.filter(s => s.type === "Tree");
if (trees.length === 0)
{
log("Please select an output from Mixed-Mode Cluster Analysis, Latent Class Analysis, or Mixed-Mode Trees.");
return false;
}
trees.forEach(function(tree) {
let dependants = tree.dependants(false);
const data_file = dependants[0].type === "Variable" ? dependants[0].question.dataFile : dependants[0].dataFile;
let page = project.currentPage === undefined ? false : project.currentPage();
if (!page)
page = tree.group;
if (!tree.analysisReports)
{
if (!!Q.isOnTheWeb && Q.isOnTheWeb())
log("The Analysis Report was not saved with this output (" + tree.name +
") when it was originally created. Please rerun it, which " +
"will ensure the report is saved and then try again.");
else
log("Sorry, you must upgrade Q to use this feature.");
return;
}
// Changing name of tree changes name of saved segments variable
// Use this to identify segments variable in data file
let question_names = data_file.questions.map(q => q.name);
let tree_name = tree.name;
const tmp_str = "TemporaryQuestionName65xg1t8ke82xhek";
tree.name = tmp_str;
let chg_idx = data_file.questions.map(q => q.name).indexOf(tmp_str);
let segments = data_file.questions[chg_idx];
segments.name = question_names[chg_idx];
tree.name = tree_name;
dependants = dependants.concat(segments);
let disambiguate_names = false;
let input_names = dependants.map(d => d.name);
let r_code = "library(digest)\n" +
"library(flipTransformations)\n" +
"inputs <- list(`" + input_names.join("`,`") + "`)\n" +
"hashes <- vapply(inputs, function(v){\n" +
" vals <- unlist(AsNumeric(v, FALSE))\n" +
" attributes(vals) <- NULL\n" +
" digest(vals)\n}, '')";
let r_output = page.appendR(r_code);
if (r_output.error !== null) {
if (/R code is ambiguous/.test(r_output.error)) {
disambiguate_names = true;
input_names = disambiguateDependantNames(dependants);
r_code = "library(digest)\n" +
"library(flipTransformations)\n" +
"inputs <- list(" + input_names.join(",") + ")\n" +
"hashes <- vapply(inputs, function(v){\n" +
" vals <- unlist(AsNumeric(v, FALSE))\n" +
" attributes(vals) <- NULL\n" +
" digest(vals)\n}, '')";
r_output.code = r_code;
r_output.update();
}else {
log("Sorry, there was an error creating your report. " +
"Please contact support. The error returned by R was: " + r_output.error);
return false;
}
}
const md5_strs = r_output.data.get([]);
r_output.deleteItem();
let output_name = generateUniqueRObjectName("analysis.report");
let names_list = disambiguate_names ? disambiguateDependantNames(dependants).join(",") : "`" + input_names.join("`,`") + "`";
r_code = 'library(digest)\n' +
'library(flipTransformations)\n' +
'md5.orig <- c("' + md5_strs.join('", "') + '")\n' +
'inputs <- list(' + names_list + ')\n' +
"md5.current <- vapply(inputs, function(v){\n" +
" vals <- unlist(AsNumeric(v, FALSE))\n" +
" attributes(vals) <- NULL\n" +
" digest(vals)\n}, '')\n" +
'if (any(md5.current != md5.orig))\n' +
' stop("Your input data has changed. Please select your tree, modify/update it if necessary, and generate a new report.")\n' +
'reports <- c("' + tree.analysisReports.join('", "').replace(/\\/ig, "\\\\") + '")\n\n' +
'library(flipFormat)\n' +
output_name + ' <- CreateAnalysisReportWidget(reports)\n';
r_output = page.appendR(r_code);
// place widget to the left or right of tree output depending on which has more room
if (tree.left > page.width - tree.left - tree.width)
r_output.left = tree.left - 100;
else
r_output.left = tree.left + 100;
r_output.top = tree.top;
project.report.setSelectedRaw([r_output]);
return;
});
return true;
}
function disambiguateDependantNames(dependants) {
return dependants.map(q => (q.type === "Question" ? "`" + q.dataFile.name + "`$Questions$`" + q.name + "`" : "`" + q.question.dataFile.name + "`$Variables$`" + q.name + "`"));
}
if (!AddAnalysisReportWidgets())
conditionallyEmptyLog("QScript canceled.");
See also
- QScript for more general information about QScripts.
- QScript Examples Library for other examples.
- Online JavaScript Libraries for the libraries of functions that can be used when writing QScripts.
- QScript Reference for information about how QScript can manipulate the different elements of a project.
- JavaScript for information about the JavaScript programming language.
- Table JavaScript and Plot JavaScript for tools for using JavaScript to modify the appearance of tables and charts.
Q Technical Reference
Q Technical Reference
Q Technical Reference > Setting Up Data > Creating New Variables
Q Technical Reference > Updating and Automation > Automation Online Library
Q Technical Reference > Updating and Automation > JavaScript > QScript > QScript Examples Library > QScript Online Library