Normalize (reformat) cross-tab data for Tableau without using Excel

后端 未结 3 2151
抹茶落季
抹茶落季 2021-01-04 06:57

Tableau generally works best when input data is in \"normalized\" format, rather than cross-tab. This is also referred to as converting from \"wide format\" to \"long format

3条回答
  •  攒了一身酷
    2021-01-04 07:39

    Well, you can use this handy Google Sheets script I made.

    enter image description here

    /*
    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(
        '' + 
        '' +
        '' + 
        '' +
        '

    Convert cross-tab

    '+ '

    This macro converts cross-tab data which has multiple dependent variables (eg, observations, sales figures) per row into a normalized format with one dependent variable per row.

    ' + '

    The name of each dependent variable becomes the value of a new column called Field and its value goes in a column called Value.

    ' + '
    1. Move all independent variable columns to the left
    2. ' + '
    3. Place the cursor in the first dependent variable column
    '+ '

    ' + '

    ' + '

    ' + '

    More information

    ') .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; }

    Full write-up with instructions on how to install.

提交回复
热议问题