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.
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>