Public
Edited
Feb 23, 2023
12 forks
Importers
9 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
files
Insert cell
Insert cell
enrollment = files["college-enrollment"]
Insert cell
Insert cell
enrollmentTotal = enrollment.filter(d => d.category == "Total")
Insert cell
faculty = files["instructional-faculty"]
Insert cell
facultyTotal = faculty.filter(d => d.category == "Total")
Insert cell
Insert cell
Plot.plot({
marks: [
Plot.ruleY([0]),
Plot.lineY(enrollmentTotal, {
x: "year",
y: "value",
marker: "dot",
stroke: "steelblue"
}),
Plot.lineY(facultyTotal, {
x: "year",
y: "value",
marker: "dot",
stroke: "orange"
})
],
y: { type: "log" },
marginLeft: 70
})
Insert cell
Insert cell
Plot.plot({
caption: `${sentenceName(dataset)}`,
marks: [
Plot.dot(data, {
x: "year",
y: "name",
fill: "value",
stroke: "gray",
title: "value"
})
],
color: { scheme: "greens" },
y: { axis: "right" },
grid: true,
width,
marginRight: 400
})
Insert cell
dataset
Insert cell
Insert cell
function tidy(rows) {
// expects a CSV parsed with type: true and array: true
// we want to turn the "wide" table where each column is a year, into a tidy table where each row is a year and value pair
// there is a nested structure where categories are broken down into separate rows, so we parse them
const hierarchy = [];
const values = [];
const years = rows[0].slice(1);

// each row is a category (starting with the series total)
for (const row of rows.slice(1)) {
let name = row[0];
// null value indicates the end of the table (there are sources metadata below the null row)
if (!name) break;

// count the number of spaces to determine the depth
const depth = name.match(/^ */)[0].length / 4;
hierarchy[depth] = name.trim();
name = hierarchy
.slice(0, depth + 1)
.reverse()
.join(" / ");
const category = hierarchy.slice(1, depth).reverse().join(" / ") || "Total";

// grab all the values for the row (after the name)
const r = row.slice(1);
for (const [i, year] of years.entries()) {
const value = r[i];
if (value != null)
values.push({
name,
category,
series: hierarchy[0],
year: new Date(Date.UTC(+year, 0, 1)), // we convert the year as a number into a UTC Date
value
});
}
}

return values;
}
Insert cell
files = ({
"college-enrollment": tidy(
await FileAttachment("college_enrollment_usafacts.csv").csv({
typed: true,
array: true
})
),
"college-enrollment-rate": tidy(
await FileAttachment("college_enrollment_rate_usafacts.csv").csv({
typed: true,
array: true
})
),
"college-graduation-rate-2-year-institutions-within-3-years-by-starting-year":
tidy(
await FileAttachment(
"college_graduation_rate_at_twoyear_institutions_within_three_years_of_start_usafacts.csv"
).csv({ typed: true, array: true })
),
"college-graduation-rate-4-year-institutions-within-6-years-by-starting-year":
tidy(
await FileAttachment(
"college_graduation_rate_at_fouryear_institutions_within_six_years_of_start_usafacts.csv"
).csv({ typed: true, array: true })
),
"bachelors-degrees": tidy(
await FileAttachment("bachelors_degrees_conferred_usafacts.csv").csv({
typed: true,
array: true
})
),
"masters-degrees": tidy(
await FileAttachment("masters_degrees_conferred_usafacts.csv").csv({
typed: true,
array: true
})
),
"doctors-degrees": tidy(
await FileAttachment("doctors_degrees_usafacts.csv").csv({
typed: true,
array: true
})
),
"instructional-faculty": tidy(
await FileAttachment("instructional_faculty_usafacts.csv").csv({
typed: true,
array: true
})
),
"avg-higher-ed-instructional-full-time-faculty-salary": tidy(
await FileAttachment(
"average_fulltime_instructional_faculty_salary_usafacts.csv"
).csv({ typed: true, array: true })
),
"median-annual-earnings-of-workers-25-34-years-old-2016-dollars": tidy(
await FileAttachment(
"inflationadjusted_median_annual_earnings_of_fulltime_workers_aged_2534_usafacts.csv"
).csv({ typed: true, array: true })
),
"average-student-loan-awarded": tidy(
await FileAttachment("average_student_loan_awarded_usafacts.csv").csv({
typed: true,
array: true
})
),
"average-student-loan-awarded-inflation-adjusted": tidy(
await FileAttachment(
"average_student_loan_awarded_inflation_usafacts.csv"
).csv({ typed: true, array: true })
),
"stem-degrees-conferred-postsecondary-institutions": tidy(
await FileAttachment(
"stem_degrees_conferred_by_postsecondary_institutions_usafacts.csv"
).csv({ typed: true, array: true })
)
})
Insert cell
sentenceName = (name) => {
const sent = name.split("-").join(" ");
return sent[0].toUpperCase() + sent.slice(1);
}
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