I have a dataset that looks like this in csv format:
continents countries values
Europe Germany 20
Europe France 30
Europe Spain 40
Asia Singapore 100
Asia Japan 300
Asia China 30
Asia Tiwan 500
America USA 50
America Canada 35
America Brazil 30
America Equador 14
When I parse it using d3.csv
and map
then the data looks like this:
[
{continents: "Europe", countries: "Germany", values: 20}
{continents: "Europe", countries: "France", values: 30}
{continents: "Europe", countries: "Spain", values: 40} and so forth. ]
What I'd like to do is to convert the format into wide one by continents group, so that the data looks like this
[
{continents: "Europe",
values: {"Germany" : 20},
{"France" : 30},
{"Spain" : 40}},
{continents: "Asia",
values: {"Singapore" : 100},
{"Japan" : 300},
{"China" : 30}}
]
That's how I'm doing at the moment.
d3.csv("/data/data.csv").then(function(csv) {
data = csv.map(function(d) {
return {
continents: d.continents,
countries: d.countries,
values: +d.values}
});
The format doesn't need to be exactly the same like the example above but the point is to make key:value pairs with country and values which belong to their respective continents group.
Could anyone let me know how to make?
Updated to use d3.nest
d3.nest
is d3's object for grouping data. You can use it to get you most of the way and then perform a quick transformation afterward:
var groups = d3.nest().key(d => d.continents).entries(rows),
result = groups.map(function(d){
return {
continents: d.key,
values: d.values
};
This will produce something like:
[{"continents":"Europe",
"values":[
{"continents":"Europe","countries":"Germany","values":"20"}, ...
],
},
{"continents":"Asia",
"values": [...]
}, ... ]
Alternative: used3.group
Another way you can get most of the way there is using d3.group
, which is part of d3-array
:
var groups = Array.from(d3.group(rows, d => d.continents));
You can then use these groups
to get the object you wanted:
groups.map(function(d){
return {
continents: d[0],
values: d[1]
};
});