Covid-19-data: Data Issue: Potential Bug in NYT javascript for covid charts (build/js/curve-grid.js)

Created on 10 Jul 2020  路  4Comments  路  Source: nytimes/covid-19-data

Describe the issue:

  • [ ] Incorrect number of cases or deaths
  • [ ] Suspicious number of cases or deaths
  • [ ] Missing data for a locality
  • [ ] Missing time-series information
  • [x] Other

Code: https://static01.nyt.com/newsgraphics/2020/03/16/coronavirus-maps/e3cd619c2996c2e2e55f086ef49ff7a0f52a36e5/build/js/curve-grid.js

Fuller details

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;
    }
data-issue

Most helpful comment

Thank you. We've relayed this to the appropriate folks!

All 4 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

briancpark picture briancpark  路  3Comments

harley164 picture harley164  路  5Comments

murphystout picture murphystout  路  5Comments

ereinecke picture ereinecke  路  4Comments

knwpsk picture knwpsk  路  4Comments