【问题标题】:Converting Dataset from 'Wide' to 'Long' in Google Apps Script for Google Sheet在 Google 表格的 Google Apps 脚本中将数据集从“宽”转换为“长”
【发布时间】:2018-04-20 04:09:59
【问题描述】:

我需要一些帮助来为这个生成一个谷歌脚本和/或公式..

在下面附加的 gsheet 中,我有以下原始数据集...

对于第 1 阶段,我需要将此“宽”格式转换为“长”格式,从而为“数据类型”中的每个属性创建新列,并将“T1”和“T2”压缩在它们自己的列中,称为'时间'。请看下面...

对于第 2 阶段,我需要加入每行的所有信息,但按“时间”分割。请看下面...

最后,对于第 3 阶段,我需要创建一个额外的步骤,每个步骤都由 Col A 拆分。请参见下文...

我试图通过“QUERY”和“Transpose”实现数据的重塑,但似乎无法做到。如果有人有一个自定义构建功能来解决这个非常常见的任务,我将非常感谢您在这方面的帮助!

数据集如下... https://docs.google.com/spreadsheets/d/1Ujxki1wmaLmkBgZQHI-OTwSubKdlN5mvLDdGWhCBn3E/edit?usp=sharing

谢谢。

【问题讨论】:

    标签: google-apps-script google-sheets


    【解决方案1】:

    这个示例脚本怎么样?我对你的问题的情况感兴趣。所以我对此提出了挑战。这也是为了我的学习。在我的回答中,我尝试使用 GAS 解决您的问题。我认为您的情况有几个答案。因此,请将此视为其中之一。

    在此示例脚本中,“阶段 1”、“阶段 2”和“阶段 3”的值每 1 个数据周期创建一次。从您的问题和示例电子表格中,我认为数据的周期是 5。然后,将创建的值导入 3 张。

    示例脚本:

    function myFunction() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var rawData = ss.getSheetByName("Raw Data").getDataRange().getValues();
      var header = rawData[0];
      var delimiter = "| "; // Please input delimiter.
      var cycle = 5; // From your question, I thought the cycle of data is 5.
    
      var phase1 = [];
      var phase2 = [];
      var phase3 = [];
      rawData.shift();
      for (var i = 0; i < rawData.length; i += cycle) {
        var temp1 = [];
        var temp2 = [];
        for (var j = i; j < i + cycle; j++) {
          temp1.push([rawData[j][0], rawData[j][1]]);
          temp2.push([rawData[j][3], rawData[j][4]]);
        }
        var converted = temp2[0].map(function(_, i){return temp2.map(function(f){return f[i]})}) // Transpose
                                .map(function(e, i){return temp1[i].concat(e).concat(header[i + 3])}); // Add T1 and T2
    
        // Create value for phase1.
        Array.prototype.push.apply(phase1, converted);
    
        // Create value for phase2.
        phase2.push([converted[0].slice(0, 7).join(delimiter), converted[1].slice(0, 7).join(delimiter)]);
    
        // Create value for phase3.
        phase3.push([converted[0][0], header[3], header[4]]);
        phase3.push(["", converted[0].slice(1, 7).join(delimiter), converted[1].slice(1, 7).join(delimiter)]);
        phase3.push(["", "", ""]);
      }
    
      // If you want to change the sheet name, please modify this part.
      var all = [
        [ss.getSheetByName("Phase 1"), phase1],
        [ss.getSheetByName("Phase 2"), phase2],
        [ss.getSheetByName("Phase 3(Desired Final Output)"), phase3]
      ];
      all.forEach(function(e) {
        // Import values to 3 sheets.
        e[0].getRange(e[0].getLastRow() + 1, 1, e[1].length, e[1][0].length).setValues(e[1]);
      });
    }
    

    如果我误解了你的问题,我很抱歉。

    编辑

    1. 运行修改后的脚本时,阶段 1、阶段 2 和阶段 3 的 3 张工作表的所有转换值都将被覆盖。
    2. Data Melt 的名称不能用作函数名称。所以DataMelt 被用于它。
      • 例如,=DataMelt('Raw Data'!A2:E6) 被放入单元格,第 1 阶段的转换数据被导入。
      • 在这个函数中,可以使用5行1周期的数据。

    修改后的脚本

    function myFunction() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var rawData = ss.getSheetByName("Raw Data").getDataRange().getValues();
      var header = rawData[0];
      var delimiter = "| "; // Please input delimiter.
      var cycle = 5; // From your question, I thought the cycle of data is 5.
    
      var phase1 = [];
      var phase2 = [];
      var phase3 = [];
      rawData.shift();
      for (var i = 0; i < rawData.length; i += cycle) {
        var temp1 = [];
        var temp2 = [];
        for (var j = i; j < i + cycle; j++) {
          temp1.push([rawData[j][0], rawData[j][1]]);
          temp2.push([rawData[j][3], rawData[j][4]]);
        }
        var converted = temp2[0].map(function(_, i){return temp2.map(function(f){return f[i]})}) // Transpose
                                .map(function(e, i){return temp1[i].concat(e).concat(header[i + 3])}); // Add T1 and T2
    
        // Create value for phase1.
        Array.prototype.push.apply(phase1, converted);
    
        // Create value for phase2.
        phase2.push([converted[0].slice(0, 7).join(delimiter), converted[1].slice(0, 7).join(delimiter)]);
    
        // Create value for phase3.
        phase3.push([converted[0][0], header[3], header[4]]);
        phase3.push(["", converted[0].slice(1, 7).join(delimiter), converted[1].slice(1, 7).join(delimiter)]);
        phase3.push(["", "", ""]);
      }
      phase1.unshift(["Col A", "Col B", "Catalogue", "Display", "Equivalent Single Price", "In-Store_Shopper", "Mechanic", "Time"]);
      phase2.unshift(["T1", "T2"]);
      var all = [
        [ss.getSheetByName("Phase 1"), phase1],
        [ss.getSheetByName("Phase 2"), phase2],
        [ss.getSheetByName("Phase 3(Desired Final Output)"), phase3]
      ];
      all.forEach(function(e) {
        // Import values to 3 sheets.
        e[0].getRange(1, 1, e[1].length, e[1][0].length).setValues(e[1]);
      });
    }
    
    // Added new function
    function DataMelt(e) {
      var e = [["Chalk","A0C-Len Superior Kids TP 80gm","Catalogue","No","Yes"],["Chalk","A0C-Len Superior Kids TP 80gm","Display","Shelf","GE"],["Chalk","A0C-Len Superior Kids TP 80gm","Equivalent Single Price",2.49,2.49],["Chalk","A0C-Len Superior Kids TP 80gm","In-Store_Shopper","",""],["Chalk","A0C-Len Superior Kids TP 80gm","Mechanic","LDLP","Off"]];
    
      var rawData = e;
      var header = ["Col A", "Col B", "Data Type", "T1", "T2"];
      var cycle = 5; // From your question, I thought the cycle of data is 5.
      var phase1 = [];
      var temp1 = [];
      var temp2 = [];
      for (var j = 0; j < cycle; j++) {
        temp1.push([rawData[j][0], rawData[j][1]]);
        temp2.push([rawData[j][3], rawData[j][4]]);
      }
      var converted = temp2[0].map(function(_, i){return temp2.map(function(f){return f[i]})}) // Transpose
                              .map(function(e, i){return temp1[i].concat(e).concat(header[i + 3])}); // Add T1 and T2
    
      // Create value for phase1.
      Array.prototype.push.apply(phase1, converted);
      return phase1;
    }
    

    【讨论】:

    • @Tanaike 非常感谢你。在这个时间点,我有两个问题 1.) 在原始数据选项卡中编辑数据时,是否可以调整脚本以替换阶段 1、阶段 2 和阶段 3 中的所有数据? (而不是像现在那样简单地将所有导入的值附加到下一个可用的空行)。 2) 是否可以创建一个名为“Data Melt”的自定义函数,在其中我可以将原始数据作为参数解析并产生与阶段 1 相同的输出?
    • @jwlon81 很抱歉给您带来不便。我更新了我的答案。请证实。如果修改后的脚本不起作用,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 2021-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多