在不使用 Excel 的情况下为 Tableau 标准化(重新格式化)cross-tab 数据
Normalize (reformat) cross-tab data for Tableau without using Excel
Tableau 通常在 input data is in "normalized" format 时效果最佳,而不是 cross-tab。这也称为从 "wide format" 转换为 "long format"。
即转换自:
收件人:
Tableau 提供了 "reshaping tool" for Excel users,但如果您没有 Excel,您就会被卡住。
那么如何在不使用 Excel 的情况下将电子表格转换为这种格式?
嗯,你可以用这个我做的得心应手Google Sheets script
/*
normalizeCrossTab: Converts crosstab format to normalized form. Given columns abcDE, the user puts the cursor somewhere in column D.
The result is a new sheet, NormalizedResult, like this:
a b c Field Value
a1 b1 c1 D D1
a1 b1 c1 E E1
a2 b2 c2 D D2
a2 b2 c2 E E2
...
Author:
Steve Bennett
stevage@gmail.com
@stevage1
Licence: Public Domain
*/
function start() {
var html = HtmlService.createHtmlOutput(
'<style>ol { padding-left: 1.5em; }</style>' +
'<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>' +
'<script>' +
'function allDone(msg) { ' +
' $("#normalizeBtn").hide();' +
' $("#datacols-output").html("<p>Your normalized data is in a sheet called NormalizedResult. If you run the normalization again, that sheet will be deleted and replaced.</p>");' +
'};' +
'function gotCols(cols) { ' +
' $("#datacols-output").html(\'<p>These will be your dependent variables:</p><ul id="datacols"></ul>\'); ' +
' $("#normalizeBtn").show();' +
' $.each(cols, function() {' +
' $("#datacols").append($("<li>").text(this)); ' +
' });' +
' $("#datacols").after("<p>If they don\'t look right, move the cursor and press <i>Continue</i>.</p>"); ' +
'}' +
'</script>' +
'<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">' +
'<h2>Convert cross-tab</h2>'+
'<p>This macro converts <i>cross-tab</i> data which has multiple dependent variables (eg, observations, sales figures) per row into a <i>normalized</i> format with one dependent variable per row.</p>' +
'<p>The name of each dependent variable becomes the value of a new column called <code>Field</code> and its value goes in a column called <code>Value</code>.</p>' +
'<ol><li>Move <b>all independent variable columns to the left</b></li>' +
' <li>Place the <b>cursor in the first dependent variable column</li></ol>'+
'<p><button onClick="google.script.run.withSuccessHandler(gotCols).getDataColumns();">Continue</button></p>' +
'<p id="datacols-output"></p>' +
'<p><button id="normalizeBtn" class="create" style="display:none;" onClick="google.script.run.withSuccessHandler(allDone).normalizeCrosstab(true);">Normalize</button></p>' +
'<br/><p><a target="_blank" href="http://kb.tableausoftware.com/articles/knowledgebase/denormalize-data">More information</a></p>')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('Normalize cross-tab')
.setWidth(300);
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showSidebar(html);
}
function onOpen() {
var ss = SpreadsheetApp.getActive();
var items = [
{name: 'Normalize Crosstab', functionName: 'start'},
];
ss.addMenu('Normalize', items);
}
function normalizeCrosstab(really) {
if (!really) {
return start();
}
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var firstDataCol = SpreadsheetApp.getActiveRange().getColumn();
var dataCols = values[0].slice(firstDataCol-1);
var resultssheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("NormalizedResult");
if (resultssheet != null) {
SpreadsheetApp.getActive().deleteSheet(resultssheet);
}
var header = values[0].slice(0, firstDataCol - 1);
var newRows = [];
header.push("Field");
header.push("Value");
newRows.push(header);
for (var i = 1; i <= numRows - 1; i++) {
var row = values[i];
for (var datacol = 0; datacol < dataCols.length; datacol ++) {
newRow = row.slice(0, firstDataCol - 1); // copy repeating portion of each row
newRow.push(values[0][firstDataCol - 1 + datacol]); // field name
newRow.push(values[i][firstDataCol - 1 + datacol]); // field value
newRows.push(newRow);
}
}
var newSheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet("NormalizedResult");
var r = newSheet.getRange(1,1,newRows.length, header.length);
r.setValues(newRows);
};
function getDataColumns() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var values = rows.getValues();
var firstDataCol = SpreadsheetApp.getActiveRange().getColumn();
var dataCols = values[0].slice(firstDataCol-1);
return dataCols;
}
较新版本的 Tableau(9.0 及更高版本)允许在导入时重塑数据。就像选择要堆叠的列一样简单。 Here's a useful tutorial.
2018 年,Tableau 发布了 Tableau Prep Builder 重塑和整理数据以进行分析。
其他一些可用于重塑和清理值得研究的数据的商业工具是:
Trifacta 是由参与先前学术 DataWrangler 项目的一些人创建的。我听说 Alteryx 非常适合地理空间相关数据的一些准备任务,并且遇到了一些热心的 Paxata 用户。
我对他们的实际操作经验太少,只能参考他们的网站,倾向于使用 Python 脚本来代替日期。
如果你想"fold"列你想合并成一个单独的列。 Tableau 写了一个有用的 tutorial here。 Tableau 9 引入了一些有用的重塑功能,用于逆透视表和拆分列。
如果您熟悉命令行和使用管道组合小工具的 Unix 风格,请查看开源 csvkit 工具套件。
您可以通过多种方式组合这些实用程序以获得不同的效果,因此具体的步骤顺序取决于您的数据集(毕竟这是工具的重点)。
但对于重塑任务,您可以使用 csvcut 提取感兴趣的列,csvgrep 提取感兴趣的行,cvsstack 将多个 csv 文件组合成一个较长的文件,以及 -g 和 -n 选项以添加分组字段。
还有其他几个有用的命令,如果您熟悉 Unix 或 linux,您可以仅从命令名称快速了解它们的作用。
Tableau 通常在 input data is in "normalized" format 时效果最佳,而不是 cross-tab。这也称为从 "wide format" 转换为 "long format"。
即转换自:
收件人:
Tableau 提供了 "reshaping tool" for Excel users,但如果您没有 Excel,您就会被卡住。
那么如何在不使用 Excel 的情况下将电子表格转换为这种格式?
嗯,你可以用这个我做的得心应手Google Sheets script
/*
normalizeCrossTab: Converts crosstab format to normalized form. Given columns abcDE, the user puts the cursor somewhere in column D.
The result is a new sheet, NormalizedResult, like this:
a b c Field Value
a1 b1 c1 D D1
a1 b1 c1 E E1
a2 b2 c2 D D2
a2 b2 c2 E E2
...
Author:
Steve Bennett
stevage@gmail.com
@stevage1
Licence: Public Domain
*/
function start() {
var html = HtmlService.createHtmlOutput(
'<style>ol { padding-left: 1.5em; }</style>' +
'<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>' +
'<script>' +
'function allDone(msg) { ' +
' $("#normalizeBtn").hide();' +
' $("#datacols-output").html("<p>Your normalized data is in a sheet called NormalizedResult. If you run the normalization again, that sheet will be deleted and replaced.</p>");' +
'};' +
'function gotCols(cols) { ' +
' $("#datacols-output").html(\'<p>These will be your dependent variables:</p><ul id="datacols"></ul>\'); ' +
' $("#normalizeBtn").show();' +
' $.each(cols, function() {' +
' $("#datacols").append($("<li>").text(this)); ' +
' });' +
' $("#datacols").after("<p>If they don\'t look right, move the cursor and press <i>Continue</i>.</p>"); ' +
'}' +
'</script>' +
'<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">' +
'<h2>Convert cross-tab</h2>'+
'<p>This macro converts <i>cross-tab</i> data which has multiple dependent variables (eg, observations, sales figures) per row into a <i>normalized</i> format with one dependent variable per row.</p>' +
'<p>The name of each dependent variable becomes the value of a new column called <code>Field</code> and its value goes in a column called <code>Value</code>.</p>' +
'<ol><li>Move <b>all independent variable columns to the left</b></li>' +
' <li>Place the <b>cursor in the first dependent variable column</li></ol>'+
'<p><button onClick="google.script.run.withSuccessHandler(gotCols).getDataColumns();">Continue</button></p>' +
'<p id="datacols-output"></p>' +
'<p><button id="normalizeBtn" class="create" style="display:none;" onClick="google.script.run.withSuccessHandler(allDone).normalizeCrosstab(true);">Normalize</button></p>' +
'<br/><p><a target="_blank" href="http://kb.tableausoftware.com/articles/knowledgebase/denormalize-data">More information</a></p>')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('Normalize cross-tab')
.setWidth(300);
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showSidebar(html);
}
function onOpen() {
var ss = SpreadsheetApp.getActive();
var items = [
{name: 'Normalize Crosstab', functionName: 'start'},
];
ss.addMenu('Normalize', items);
}
function normalizeCrosstab(really) {
if (!really) {
return start();
}
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var firstDataCol = SpreadsheetApp.getActiveRange().getColumn();
var dataCols = values[0].slice(firstDataCol-1);
var resultssheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("NormalizedResult");
if (resultssheet != null) {
SpreadsheetApp.getActive().deleteSheet(resultssheet);
}
var header = values[0].slice(0, firstDataCol - 1);
var newRows = [];
header.push("Field");
header.push("Value");
newRows.push(header);
for (var i = 1; i <= numRows - 1; i++) {
var row = values[i];
for (var datacol = 0; datacol < dataCols.length; datacol ++) {
newRow = row.slice(0, firstDataCol - 1); // copy repeating portion of each row
newRow.push(values[0][firstDataCol - 1 + datacol]); // field name
newRow.push(values[i][firstDataCol - 1 + datacol]); // field value
newRows.push(newRow);
}
}
var newSheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet("NormalizedResult");
var r = newSheet.getRange(1,1,newRows.length, header.length);
r.setValues(newRows);
};
function getDataColumns() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var values = rows.getValues();
var firstDataCol = SpreadsheetApp.getActiveRange().getColumn();
var dataCols = values[0].slice(firstDataCol-1);
return dataCols;
}
较新版本的 Tableau(9.0 及更高版本)允许在导入时重塑数据。就像选择要堆叠的列一样简单。 Here's a useful tutorial.
2018 年,Tableau 发布了 Tableau Prep Builder 重塑和整理数据以进行分析。
其他一些可用于重塑和清理值得研究的数据的商业工具是:
Trifacta 是由参与先前学术 DataWrangler 项目的一些人创建的。我听说 Alteryx 非常适合地理空间相关数据的一些准备任务,并且遇到了一些热心的 Paxata 用户。
我对他们的实际操作经验太少,只能参考他们的网站,倾向于使用 Python 脚本来代替日期。
如果你想"fold"列你想合并成一个单独的列。 Tableau 写了一个有用的 tutorial here。 Tableau 9 引入了一些有用的重塑功能,用于逆透视表和拆分列。
如果您熟悉命令行和使用管道组合小工具的 Unix 风格,请查看开源 csvkit 工具套件。
您可以通过多种方式组合这些实用程序以获得不同的效果,因此具体的步骤顺序取决于您的数据集(毕竟这是工具的重点)。
但对于重塑任务,您可以使用 csvcut 提取感兴趣的列,csvgrep 提取感兴趣的行,cvsstack 将多个 csv 文件组合成一个较长的文件,以及 -g 和 -n 选项以添加分组字段。
还有其他几个有用的命令,如果您熟悉 Unix 或 linux,您可以仅从命令名称快速了解它们的作用。