I was doing some spelunking in the javascript on your site and think I might have caught a bug (even if it is, it's pretty trivial) in the code in your rate of change calculation. The site calls them out as being a comparison to 2 weeks prior (14 days), but it actually looks like it's comparing 13 days prior. I've bolded these below, but main points being:
Current rolling value: obj.latest_average_value_raw = obj.rolling_average_raw[obj.rolling_average_raw.length - 1];
Compared rolling value: obj.rolling_average_raw[obj.rolling_average_raw.length - 14]
Effectively what this is doing is calculating the rate of change between the current data and 13 days prior ( (length -1) - (length - 14) = 13). So for example, today's classification would be based on the difference in rolling average new cases between 7/9 and 6/26. Again, since you're doing the rolling average it's already deseasonalized, so less of an issue, more of an FYI in case other people are interested in recreating logic. I know that in https://github.com/nytimes/covid-19-data/issues/316#issuecomment-643779708 you recommend not trying to recreate NYT logic, but our business folks are particularly fond of the current color scheme and there isn't an easy way to scrape given they're stored as images :).
function makeCharts(locations, perCapita, type, sortField, use_global_y_max, logMode) {
const charts = locations.map(location => {
const obj = {};
obj.geoid = location.geoid;
obj.link = location.link;
obj.name = location.display_name;
obj.is_us_state = location.hierarchy.includes("USA");
obj.hierarchy = location.hierarchy;
obj.is_country = location.hierarchy && location.hierarchy.length === 1 && location.hierarchy[0] === "NYT-World";
//obj.total = location.all_cases[location.all_cases.length - 1]
obj.total = +location.latest;
obj.total_per_100k = +location.latest / +location.population * 100000;
obj.series_raw = location.daily[type].map(x => x < 0 ? 0 : x);
obj.series_per_capita = location.daily[type].map(x => x < 0 ? 0 : x).map(x => x / location.population * 100000);
obj.series = location.daily[type].map(x => x < 0 ? 0 : x).map(x => perCapita ? x / location.population * 100000 : x);
obj.latest_value_raw = obj.series[obj.series_raw.length - 1];
obj.latest_value_per_capita = obj.series_per_capita[obj.series_per_capita.length - 1];
obj.latest_value = obj.series[obj.series.length - 1];
obj.rolling_average_raw = location.average[type].map(x => x < 0 ? 0 : x);
obj.rolling_average_per_capita = location.average[type].map(x => x < 0 ? 0 : x).map(x => x / location.population * 100000);
obj.rolling_average = location.average[type].map(x => x < 0 ? 0 : x).map(x => perCapita ? x / location.population * 100000 : x);
obj.latest_average_value_raw = obj.rolling_average_raw[obj.rolling_average_raw.length - 1];
obj.latest_average_value_per_capita = obj.rolling_average_per_capita[obj.rolling_average_per_capita.length - 1];
obj.latest_average_value = obj.rolling_average[obj.rolling_average.length - 1];
obj.last_two_weeks_rate_of_change_raw = (obj.latest_average_value_raw / obj.rolling_average_raw[obj.rolling_average_raw.length - 14] - 1) * 100;
obj.last_two_weeks_rate_of_change_per_capita = (obj.latest_average_value_per_capita / obj.rolling_average_per_capita[obj.rolling_average_per_capita.length - 14] - 1) * 100;
obj.last_two_weeks_rate_of_change = (obj.latest_average_value / obj.rolling_average[obj.rolling_average.length - 14] - 1) * 100;
obj.y_max_raw = Math.max(...obj.rolling_average_raw);
obj.y_max = Math.max(...obj.rolling_average);
return obj;
}).sort((a, b) => {
return a[sortField] > b[sortField] ? -1 : 1;
});
return charts;
}
Thank you. We've relayed this to the appropriate folks!
Thanks @bsaunders23 we noticed that too, seemed odd to us also. We also noticed what we believe to be an issue in the code re the coloration and the %'s used, - will post that later when I get a moment.
@jazz788 that'd be greatly appreciated!
@bsaunders23 Have forgotten to update it here but we did make a change here and are now subtracting 15 instead of 14 to make the comparison compare to the same weekday two weeks before. Thanks for raising this.
Most helpful comment
Thank you. We've relayed this to the appropriate folks!