Public
Edited
Oct 24, 2024
Importers
3 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Set a start year for our analysis
start_year = 1900
Insert cell
Insert cell
// https://www2.census.gov/library/stories/2018/08/coastline-counties-list.xlsx
coastline_counties = (await FileAttachment("census-coastline-counties-2016@1.json").json())
.map(d => (d.fips = d.fips.toString(), d.year = 2016, d.population = d.population_est_2016, d)) // Ensure FIPS codes are strings
Insert cell
hurricane_counties = coastline_counties
.filter(d => d.coastline_region !== "Pacific") // We only want the Atlantic and Gulf of Mexico
Insert cell
hurricane_counties_fips = hurricane_counties
.map(d => d.fips) // Just unique FIPS codes
Insert cell
Insert cell
counties_1900_1990 = (await FileAttachment("cencounts.csv").csv())
.map(d => (d.fips = d.fips === "12025" ? "12086" : d.fips, d)) // Dade County (FIPS code 12025) was renamed Miami–Dade County and changed its FIPS code to 12086 in 1997. https://www.hamiltonproject.org/assets/files/PBP_Framing_TechAppendix.pdf
Insert cell
// Make a tall version of the data (each row is a year-county)
counties_1900_1990_tall = d3
.range(1900, 1970, 10)
.map(year => {
return counties_1900_1990.map(county => {
return {
year,
fips: county.fips,
population: +county[`pop${year}`]
}
})
})
.flat()
Insert cell
Insert cell
// via https://coast.noaa.gov/digitalcoast/data/
shoreline_counties = (await FileAttachment("DemographicTrends_ShorelineCounties@1.csv").csv())
.map(d => (d.fips = d.fips.padStart(5, 0), d.year = +d.year, d.population = +d.c_popul, d))
Insert cell
// Combine the data
counties = [
...counties_1900_1990_tall
.filter(f => hurricane_counties_fips.includes(f.fips)) // only use the Atlantic and Gulf of Mexico counties
.map(d => {
const l = shoreline_counties.find(f => f.fips === d.fips);
return {
fips: d.fips,
year: d.year,
population: d.population,
ctystate: l.ctystate,
st_abbr: l.st_abbr
}
}),
...shoreline_counties
.filter(f => hurricane_counties_fips.includes(f.fips)) // only use the Atlantic and Gulf of Mexico counties
.filter(f => f.year >= start_year)
,
...hurricane_counties.map(d => {
const l = shoreline_counties.find(f => f.fips === d.fips);
return {
fips: d.fips,
year: d.year,
population: d.population,
ctystate: l.ctystate,
st_abbr: l.st_abbr
}
})
]
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Function to interpolate between two known points using exponential interpolation
function P(t0, P0, t1, P1, t) {
const r = Math.log(P1 / P0) / (t1 - t0);
return P0 * Math.exp(r * (t - t0));
}
Insert cell
// Generate annual data
function generateAnnualData(decennialData, endYear) {
let data = [];

// Interpolate between decennial years, but stop at 2010 (do not go beyond 2010)
for (let i = 0; i < decennialData.length - 1; i++) {
const startYear = decennialData[i].year;
const startPopulation = decennialData[i].population;
const endYearDecade = decennialData[i + 1].year;
const endPopulation = decennialData[i + 1].population;

// Only interpolate up to 2010 (exclude 2011-2015)
for (let year = startYear; year < Math.min(endYearDecade, 2011); year++) {
const population = P(startYear, startPopulation, endYearDecade, endPopulation, year);
data.push({ year, population });
}
}

// Interpolate between 2010 and 2016 (for 2011 to 2015)
const year2010 = decennialData.find(d => d.year === 2010);
const year2016 = { year: 2016, population: decennialData[decennialData.length - 1].population };
for (let year = 2011; year < year2016.year; year++) {
const population = P(year2010.year, year2010.population, year2016.year, year2016.population, year);
data.push({ year, population });
}

// Extrapolate from 2016 to 2017 using the growth rate from 2010-2016
const growthRate2010to2016 = Math.log(year2016.population / year2010.population) / (year2016.year - year2010.year);
for (let year = year2016.year; year <= endYear; year++) {
const population = year2016.population * Math.exp(growthRate2010to2016 * (year - year2016.year));
data.push({ year, population });
}

return data;
}

Insert cell
// Sum the coastline data in each year
coastline_decadal = d3
.groups(counties, d => d.year)
.map(([year, entries]) => ({year, population: d3.sum(entries, d => d.population)}))
Insert cell
Insert cell
Insert cell
coastline_annual = generateAnnualData(coastline_decadal, 2017)
.map(d => {
// Calculate wealth using Weinkle et. al.'s annual per capita wealth
d.wealth = d.population * weinkle_inflation_wealth.find(f => f.year === d.year).real_wealth_per_cap;
return d;
});
Insert cell
Insert cell
Insert cell
Insert cell
// From the "Storm Damages" tab in the Excel file
weinkle_damages = FileAttachment("weinkle_damages.json").json()
Insert cell
// From the "Inflation & Wealth" tab in the Excel file
weinkle_inflation_wealth = FileAttachment("weinkle_inflation_wealth.json").json()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
data_hurricanes = d3
.range(start_year, 2018)
.map(year => {
const { count, count_major, inflation, normalized } = damages_annual.find(d => d.year === year);
const { population, wealth } = coastline_annual.find(d => d.year === year);

return {
year,
count,
count_major,
inflation,
normalized,
population,
wealth
}
})
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more