The core function: the rows of one dataset at one detail level, as a tibble typed from the dataset's schema, with place names beside their codes.
It returns every category and group the filters don't exclude. Nothing is pinned by default: no single demographic group, no single subject. A call with only a dataset name returns the whole dataset at its default detail level.
Usage
gcd_rows(
name,
...,
year = NULL,
detail = NULL,
district = NULL,
school = NULL,
county = NULL,
labels = TRUE,
columns = NULL,
sort = NULL,
n_max = Inf,
cache = getOption("gcd.cache", FALSE),
quiet = FALSE
)Arguments
- name
The dataset's name, such as
"graduation_rate_4_year_cohort"(seegcd_datasets()andgcd_search()).- ...
Named filters (see "Filters"). Unnamed arguments are an error.
- year
Years to keep, an integer vector. A run of consecutive years (
2019:2024) is sent as a range; anything else (c(2019, 2024)) as exact years. DefaultNULL: all years.- detail
The one level the rows describe, such as
"schools","districts","states","counties"or"tracts". DefaultNULL: the dataset's default (the finest level, except Census datasets, which default to counties). To combine levels, call once per level and bind the rows.- district, school, county
Places by name, such as
district = "Fulton County",school = "Roswell High School",county = c("Fulton", "DeKalb"). Matched exactly against current and former names (ignoring case, accents and a trailing "County"); an unknown or ambiguous name is an error that lists suggestions or candidates. A school name found in more than one district needsdistricttoo. For any one place, give its code or its name, not both. DefaultNULL.- labels
TRUE(default) adds place names beside codes;FALSEreturns codes only (see "Labels").- columns
A character vector to return only some columns. Default
NULL: all.- sort
A character vector of columns to sort by on the server; prefix
-for descending ("-graduation_rate"). Missing values sort last. Mostly useful withn_maxfor a top N. DefaultNULL: the dataset's own order (its grain).- n_max
The most rows to return. Default
Inf: all.- cache
TRUEto use the disk cache (see "Large downloads and the disk cache"). DefaultgetOption("gcd.cache", FALSE).- quiet
TRUEto silence the advisory messages. DefaultFALSE.
Value
A tibble of rows at one detail level, typed from the schema:
codes and names character (leading zeros kept), year integer,
counts integer, rates and proportions double (proportions on the 0-1
scale), booleans logical. Columns come in grain order: year, each
geography code followed by its names, demographic and its labels,
other categorical columns, then metrics. gcd_columns() describes
each column. The tibble carries a gcd_meta attribute (see
gcd_meta()): dataset, title, detail, key metric, units,
null_semantics, source, citation, license, advisories, data version,
updated_at and the request URL.
Filters
Give filters as named arguments in ...; each value is a vector.
Values within one filter are OR'd; different filters are AND'd.
Accepted names:
any categorical column:
subject = "mathematics",demographic = c("all", "black");geography codes:
district_code,school_code,county_fips,tract_geoid,block_group_geoid;school_id: schools as"DISTRICT-SCHOOL"codes (school_id = c("761-0199", "660-0104")), the formgcd_locate()returns (a school code alone is not unique across districts);lookup-table attributes:
district_type = "state_charter",school_level = "high",locale = "rural",demographic_category = "race";metric bounds:
graduation_rate_min = 0.9,num_cohort_max = 50(inclusive, in stored units).
NA in a filter selects rows where a nullable column is empty;
logicals become true / false. The API validates every filter and
its errors name what went wrong; gcd_describe() lists each dataset's
filters and their values.
Labels
With labels = TRUE (the default) the rows carry the API's joined name
columns, each right after its code: district_name,
district_census_id and district_type after district_code;
school_name after school_code; county_name, tract_name and
block_group_name after their codes; demographic_label and
demographic_category after demographic. Codes are always kept:
school names repeat across districts, names change over time, and joins
run on codes.
Categorical values (
subject,grade_cluster) are readable snake_case codes already; there are no separate labels for them.demographic_category(race, gender, economic_status, ...) is a grouping that arrives with the labels; filtering by it works either way.Other lookup-table attributes (school addresses, locale, coordinates) are not joined; get them from
gcd_dimension()and join.
labels = FALSE asks for the dataset's own columns only, for large
pulls. gcd_columns() takes the same argument and lists the name
columns too, with role "label". Either way, code columns that would be empty on every row (a
district row's school_code, a state row's geography codes) are left
out, so both settings give the same shape.
Missing values and totals
NA in a metric usually means the value was suppressed to protect
privacy (small counts), not zero; the schema's null_semantics says
which (gcd_describe()). Because nothing is pinned, results hold the
all totals beside the subgroups: never add a total to its subgroups.
The API's advisories say so when they apply, and print once per call as
messages (quiet = TRUE or options(gcd.quiet = TRUE) silences them;
they stay in gcd_meta(x)$advisories).
Rates must be pooled from their counts, never averaged:
sum(num_graduates) / sum(num_cohort), not mean(graduation_rate).
gcd_columns() shows each metric's numerator and denominator.
Large downloads and the disk cache
Up to 10,000 rows come back as one JSON page. A larger result is downloaded in full as CSV in one response (with a progress bar); the metadata and advisories then come from the first JSON page and describe its first 10,000 rows.
With cache = TRUE (or options(gcd.cache = TRUE)), responses are kept
in tools::R_user_dir("georgiacivicdata", "cache") with their ETag.
Repeating a request asks the server whether the data changed: an
unchanged answer reuses the saved copy without downloading, and a new
data release downloads afresh. A response the server marks fresh (for
five minutes) is reused without asking. Clear it with
gcd_cache_clear().
Data license
The data is CC BY 4.0: credit Georgia Civic Data and the original
source, as gcd_citation() writes.
See also
gcd_values() to see which category values exist under a
filter; gcd_describe() and gcd_columns() to understand a dataset;
gcd_citation() to cite it.
Other get data:
gcd_values()
Examples
if (FALSE) { # interactive()
# Names and codes (the default), one district by name
grad <- gcd_rows(
"graduation_rate_4_year_cohort",
district = "Fulton County",
demographic = c("all", "black", "hispanic"),
year = 2020:2024
)
# One school, by name within its district
gcd_rows("graduation_rate_4_year_cohort",
district = "Fulton County", school = "Roswell High School",
demographic = "all")
# Statewide schools, one subject, codes only
gcd_rows("ccrpi_content_mastery", year = 2025, detail = "schools",
grade_cluster = "high", subject = "mathematics", labels = FALSE)
# Top 10 counties by unemployment
gcd_rows("employment", year = 2024, sort = "-unemployment_rate",
n_max = 10)
}