This is my data:
data =
[{ndc_description: "VIAGRA 50 MG TABLET", new_percent_change: 12.9, year: "2017"},
{ndc_description: "VIAGRA 50 MG TABLET", new_percent_change: 12.9, year: "2019"},
{ndc_description: "VIAGRA 50 MG TABLET", new_percent_change: 12.9, year: "2017"},
{ndc_description: "JANUVIA 100 MG TABLET", new_percent_change: 4.41, year: "2017"},
{ndc_description: "JANUVIA 100 MG TABLET", new_percent_change: 4.41, year: "2019"},
{ndc_description: "JANUVIA 100 MG TABLET",new_percent_change: 4.41, year: "2017"}]
How can I mean the new_percent_change for each of two ndc_description and it's relative year? I want to add another column after "year" to contain calculated value.
Update: I could calculate the mean
roll = d3.rollups(data, v => d3.mean(v, d => d.new_percent_change), d => d.year, d => d.ndc_description)
but I don't know how to assign each value to the data array.
CodePudding user response:
Since roll
is an array of arrays with the means, you can do nested forEach
loops to find the correct data object, tio which you will pass the mean:
roll.forEach(yearArray => {
yearArray[1].forEach(description => {
const foundObj = data.filter(e => e.year === yearArray[0] && e.ndc_description === description[0]);
foundObj.forEach(obj => obj.mean = description[1])
})
});
Here's a demo, I changed some values so you can see the correct means:
const data = [{
ndc_description: "VIAGRA 50 MG TABLET",
new_percent_change: 10.9,
year: "2017"
},
{
ndc_description: "VIAGRA 50 MG TABLET",
new_percent_change: 12.3,
year: "2019"
},
{
ndc_description: "VIAGRA 50 MG TABLET",
new_percent_change: 12.9,
year: "2017"
},
{
ndc_description: "JANUVIA 100 MG TABLET",
new_percent_change: 8.41,
year: "2017"
},
{
ndc_description: "JANUVIA 100 MG TABLET",
new_percent_change: 5.41,
year: "2019"
},
{
ndc_description: "JANUVIA 100 MG TABLET",
new_percent_change: 4.41,
year: "2017"
}
];
const roll = d3.rollups(data, v => d3.mean(v, d => d.new_percent_change), d => d.year, d => d.ndc_description);
roll.forEach(yearArray => {
yearArray[1].forEach(description => {
const foundObj = data.filter(e => e.year === yearArray[0] && e.ndc_description === description[0]);
foundObj.forEach(obj => obj.mean = description[1])
})
});
console.log(data)
<script src="https://d3js.org/d3.v7.min.js"></script>