【问题标题】:how to transpose data from csv file in d3.js如何在 d3.js 中转置 csv 文件中的数据
【发布时间】:2018-02-13 08:07:00
【问题描述】:

我有一个 csv 文件,其中包含如下所述的数据:

+---+---+---+---+---+---+---+---------+
| A | B | C | D | E | F | G | Episode |
+---+---+---+---+---+---+---+---------+
| 3 | 1 | 5 | 0 | 2 | 6 | 0 | 1       |
+---+---+---+---+---+---+---+---------+

现在我想使用 d3.js 对其进行转置,这样我的最终输出将如下所示:

+----------+-------+---------+
| alphabet | value | Episode |
+----------+-------+---------+
| A        | 3     | 1       |
+----------+-------+---------+
| B        | 1     | 1       |
+----------+-------+---------+
| C        | 5     | 1       |
+----------+-------+---------+
| D        | 0     | 1       |
+----------+-------+---------+
| E        | 2     | 1       |
+----------+-------+---------+
| F        | 6     | 1       |
+----------+-------+---------+
| G        | 0     | 1       |
+----------+-------+---------+

我该怎么做?

到目前为止,我确实加载了 csv:

d3.csv("data.csv", function(error, Data){
                if(error){
                    throw error;
                }

                Data.forEach(function (d){
                     d.A = +d.A
                     .....
                     .....
             });

但是我该如何转置呢?

【问题讨论】:

    标签: javascript csv d3.js


    【解决方案1】:

    您的问题有点误导,因为您似乎想生成具有所需结构的新 CSV。

    其实你想要的是有一个这样结构的数据数组:

    [{
        alphabet: "A",
        value: 3,
        Episode: 1
    }, {
        alphabet: "B",
        value: 1,
        Episode: 1
    }, 
    //etc...
    ];
    

    当您了解d3.csv 如何解析 CSV 文件时,您可以使用此结构创建一个新的数据数组:第一行将是标题,而后面的所有行都是值。

    所以,有几种方法可以创建一个新的数据数组,这是其中之一:

    var transposedData = [];
    
    data.forEach(function(d) {
      for (var key in d) {
        var obj = {};
        if (key !== "Episode") {
          obj.alphabet = key;
          obj.value = d[key];
          obj.Episode = d.Episode;
          transposedData.push(obj)
        } 
      }
    });
    

    这是一个演示(为了完整起见,我添加了另一行第二集):

    var csv = `A,B,C,D,E,F,G,Episode
    3,1,5,0,2,6,0,1
    2,4,3,5,7,9,6,2`;
    
    var data = d3.csvParse(csv, function(d) {
      for (var key in d) {
        d[key] = +d[key];
      }
      return d;
    });
    
    var transposedData = [];
    
    data.forEach(function(d) {
      for (var key in d) {
        var obj = {};
        if (key !== "Episode") {
          obj.alphabet = key;
          obj.value = d[key];
          obj.Episode = d.Episode;
          transposedData.push(obj)
        } 
      }
    });
    
    console.log(transposedData)
    <script src="https://d3js.org/d3.v4.min.js"></script>

    【讨论】:

      【解决方案2】:

      下面的代码将原始数据存储在一个名为new_data 的数组中。它包含带有 'alphabet''value''Episode' 键的对象。

      d3.csv("data.csv", function(data){
        new_data = []
        for (var property in data) {
          if (property != 'Episode') {
            new_data.push({'alphabet': property, 'value':parseInt(data[property]), 'Episode': 1})
          }
        } 
        console.log(new_data)
      }) 
      

      new_data 数组如下所示:

      【讨论】:

      • data 是一个对象数组,而不是一个对象。另外,我猜 Episode 值应该动态确定,而不是硬编码。
      • 数据是一个对象。 console.log(typeof data) -> objectconsole.log(data) -> Object { A: "3", B: "1", C: "5", D: "0", E: "2", F: "6", G: "0", Episode: "1" }
      • 这只有在您使用 D3 v5 时才是正确的,其中 d3.csv 的第二个参数可以是行转换函数。但是,由于 OP 使用 function(error, Data) 指定两个参数,这表明使用 v4 或更低版本,其中传递给回调的参数是对象数组。此外,OP 的代码中有一个Data.forEach()
      • 啊,好点,我没有考虑版本之间的差异!我确实在使用 v5。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-27
      相关资源
      最近更新 更多