将CSV数据映射到新结构

时间:2019-01-11 20:22:26

标签: javascript csv object d3.js

我有一个包含以下数据的csv

kid_user

我阅读了这个csv文件,现在我需要整理数据。我的最终目标是获得以下输出

this_year   |   minus_one_year  |   minus_two_year  |   minus_three_year
-------------------------------------------------------------------------
1           |   2               |   2               |   3
-------------------------------------------------------------------------
4           |   5               |   5               |   5
-------------------------------------------------------------------------
2           |   2               |   2               |   2
-------------------------------------------------------------------------
4           |   5               |   4               |   4
-------------------------------------------------------------------------
1           |   2               |   3               |   3
-------------------------------------------------------------------------

因此,对于每一列,我都获得唯一值。因此this_year有3个节点,因为数据包含3个唯一值1、2和4。

我正在使用D3,但目前仅涉及解析。对于数据的格式设置,我认为我走在正确的轨道上,我在使用地图。

到目前为止,我有这样的事情

{
  "nodes": [
    {
      "name": "1",
      "node": "this_year"
    },
    {
      "name": "2",
      "node": "this_year"
    },
    {
      "name": "4",
      "node": "this_year"
    },
    {
      "name": "2",
      "node": "minus_one_year"
    },
    {
      "name": "5",
      "node": "minus_one_year"
    },
    {
      "name": "2",
      "node": "minus_two_year"
    },
    {
      "name": "3",
      "node": "minus_two_year"
    },
    {
      "name": "4",
      "node": "minus_two_year"
    },
    {
      "name": "5",
      "node": "minus_two_year"
    },
    {
      "name": "2",
      "node": "minus_three_year"
    },
    {
      "name": "3",
      "node": "minus_three_year"
    },
    {
      "name": "4",
      "node": "minus_three_year"
    },
    {
      "name": "5",
      "node": "minus_three_year"
    }
  ]
}

其中输出是csv数据。显然,这是行不通的,但是所有这些映射和归约等都让它有些困惑。因此,对于我拥有的数据,我该如何实现 以上的输出?

我包括了JSFiddle,以证明到目前为止我所做的事情。

非常感谢

更新

let graph = {"nodes" : [], "links" : []};

graph.nodes = output.map(function(d) { return [
  {
    'name': d.current_month,
    'node': d.value
  }
]; });

console.log(graph.nodes)

3 个答案:

答案 0 :(得分:2)

这是一种方法,您必须使用Object.entries()将行分成键/值,然后将新对象推送到节点。

注意Object.entries({a:100})返回一个数组["a", 100]

let graph = {"nodes" : [], "links" : []};

output.forEach(function(line) { 
    Object.entries(line).forEach(function(column){
      graph.nodes.push({
         'name': column[0],
         'node': column[1]
      })
  })
})
console.log(graph.nodes)

编辑:您还可以使用以类似方式工作的reduce函数

output.reduce(function(acc, line){
    return acc.concat(Object.entries(line).map(function(column){
        return {name: column[0], node: column[1]}
    }))}, [])

答案 1 :(得分:1)

csv中的第1行是标题。必须在节点对象中重复此操作以适合您的模型。您可以通过遍历标题然后解析csv文件的其余部分来实现此目的:

var d3 = require("d3");
let data = "this_year,minus_one_year,minus_two_year,minus_three_year\n1,2,2,3\n4,5,5,5\n2,2,2,2\n4,5,4,4\n1,2,3,3";

let output = d3.csvParseRows(data);
let nodeTitles = output[0];
let graph = {"nodes" : []};

console.log(nodeTitles);

for (var i = 0; i < nodeTitles.length; i++) {
    for (var j = 1; j < output.length; j++)
    {
        var obj = {name:output[j][i], node:nodeTitles[i]}; 
        if (!graph.nodes.some(function(element) {
            return (element.name == output[j][i]) && (element.node == nodeTitles[i]);
          }))
        {
            graph.nodes.push(obj);
        }
    }
}
console.log(graph);

答案 2 :(得分:0)

地图功能参数d没有属性“ current_month”和“ value”。而且您的SCV也没有此名称的字段。