D3 - 无论如何要获得给定标题名称的列子集?

时间:2018-03-04 01:44:02

标签: d3.js

我一直坚持试图实现这一目标已有一段时间了。我想获得给定标题名称的列的子集,但同时保留数据为csv对象。

假设我有这个csv:

type,Alabama,Alaska,Arizona,Arkansas
violent,14324,3498,21161,9181
murder,228,16,248,103
rape,1154,553,1534,874
robbery,3576,599,6132,1892
assault,9433,2330,13247,6312
property,110445,17776,181403,74226
burglary,26399,1924,37936,19363
larceny,77067,14577,129979,51346
motorTheft,6979,1275,13488,3517
arson,24,121,1028,307

如何切片并只获得阿拉斯加和阿肯色州:

type,Alaska,Arkansas
violent,14324,
murder,228,16,
rape,1154,553
robbery,3576,5992
assault,9433,2330
property,110445,17776
burglary,26399,1924
larceny,77067,14577
motorTheft,6979,1275
arson,24,121

非常感谢!

3 个答案:

答案 0 :(得分:4)

虽然这个问题得到了很好的解答,但还有另一种(imo)更加量身定制的方法来操纵这个JS对象数组 - 使用辉煌的JSONata表达式评估器库:

var jsonata = require('jsonata');
var expr = jsonata('$.$sift(function($v, $k) {$k = "type" or $k in ["Alaska", "Arkansas"]})');
var results = expr.evaluate(csvdata);

内置$sift(...)函数仅返回与谓词函数匹配的字段 - 但还有许多其他方法可以对Javascript数据进行切片和切块。 lambda function syntax需要花费一些时间来解决问题,但是对于任何需要转换JS数据的人来说都是花费时间。

甚至还有一个在线数据训练器,您可以粘贴自己的数据,键入表达式,并立即查看结果。这是example使用您自己的数据和上面的表达式。享受!

- 史蒂夫

答案 1 :(得分:1)

假设您已通过d3.csv(或d3.csvParse)加载 CSV 内容:

const data = d3.csvParse(`type,Alabama,Alaska,Arizona,Arkansas
  violent,14324,3498,21161,9181
  murder,228,16,248,103
  rape,1154,553,1534,874
  robbery,3576,599,6132,1892
  assault,9433,2330,13247,6312
  property,110445,17776,181403,74226
  burglary,26399,1924,37936,19363
  larceny,77067,14577,129979,51346
  motorTheft,6979,1275,13488,3517
  arson,24,121,1028,307`);

考虑下列要保留的列数:

const keep = ['Alaska', 'Arkansas'];

您可以使用简单的mapreduce操作,如下所示:

const sliced = data.map(row => ['type', ...keep].reduce((acc, v) => ({ ...acc, [v]: row[v] }), {}));

此处,sliced只会包含与'Alaska''Arkansas'对应的 CSV 文件的列:

[ { type: 'violent', Alaska: '3498', Arkansas: '9181' },
  { type: 'murder', Alaska: '16', Arkansas: '103' },
  { type: 'rape', Alaska: '553', Arkansas: '874' },
  { type: 'robbery', Alaska: '599', Arkansas: '1892' },
  { type: 'assault', Alaska: '2330', Arkansas: '6312' },
  { type: 'property', Alaska: '17776', Arkansas: '74226' },
  { type: 'burglary', Alaska: '1924', Arkansas: '19363' },
  { type: 'larceny', Alaska: '14577', Arkansas: '51346' },
  { type: 'motorTheft', Alaska: '1275', Arkansas: '3517' },
  { type: 'arson', Alaska: '121', Arkansas: '307' } ]

答案 2 :(得分:1)

最后解决它后再给它好几次了!

对于那些偶然发现这篇文章并且像我一样有问题的人,我就是这样解决的:

var select1 = "Alaska",
    select2 = "Arkansas";

headerBar = ["type"];   
headerBar.push(select1,select2);

var newStateData = data.map(function(dat){
    return {type:dat.type,
            [select1]: dat[select1],
            [select2]: dat[select2]
            }
    });

newStateData["columns"] = headerBar;

祝你有个美好的一天!

编辑: ccjmne与我同时发布,但他确实有一个更优雅的解决方案。所以请参考他的回答。