eeptools is an R package that makes it easier for analysts at state and local
education agencies to work with administrative records on students, schools, and
districts. It focuses on the tasks that are specific to education unit-record
data -- calculating ages and grade retention, identifying student mobility,
checking unique identifiers, and exploring example datasets -- and tries to make
those tasks simpler and less error-prone.
knitr::opts_chunk$set( cache=FALSE, comment="#>", collapse=TRUE, echo=TRUE ) library(knitr); library(eeptools)
For analysts using unit-record data of some type, there are several calc functions
which automate common tasks including calculating ages (age_calc),
grade retention (retained_calc), and student mobility (moves_calc).
age_calc(dob = as.Date('1995-01-15'), enddate = as.Date('2003-02-16'), units = "years") age_calc(dob = as.Date('1995-01-15'), enddate = as.Date('2003-02-16'), units = "months") age_calc(dob = as.Date('1995-01-15'), enddate = as.Date('2003-02-16'), units = "days")
age_calc also now properly accounts for leap years and leap seconds by default.
age_calc can be passed a vector of dates of birth and a vector of end dates or
a single end-date and produce a vector of ages as well -- suitable for computing
student age on the fly from date-of-birth records.
retained_calc takes a vector of student identifiers and a vector of grades and
checks whether or not the student was retained in the grade level specified by
the user. It returns a data.frame of all students who could have been retained
and a yes or no indicator of whether they were retained.
x <- data.frame(sid = c(101, 101, 102, 103, 103, 103, 104, 105, 105, 106, 106), grade = c(9, 10, 9, 9, 9, 10, 10, 8, 9, 7, 7)) retained_calc(df = x, sid = "sid", grade = "grade", grade_val = 9)
retained_calc is intended to be used after you have processed your data as it
does not take into account time or sequence other than the order in which the
data is passed to it.
moves_calc is intended to identify based on enrollment dates whether a student
experienced a school move within a school year.
df <- data.frame(sid = c(rep(1,3), rep(2,4), 3, rep(4,2)), schid = c(1, 2, 2, 2, 3, 1, 1, 1, 3, 1), enroll_date = as.Date(c('2004-08-26', '2004-10-01', '2005-05-01', '2004-09-01', '2004-11-03', '2005-01-11', '2005-04-02', '2004-09-26', '2004-09-01','2005-02-02'), format='%Y-%m-%d'), exit_date = as.Date(c('2004-08-26', '2005-04-10', '2005-06-15', '2004-11-02', '2005-01-10', '2005-03-01', '2005-06-15', '2005-05-30', NA, '2005-06-15'), format='%Y-%m-%d')) moves <- moves_calc(df, sid = "sid", schid = "schid", enroll_date = "enroll_date", exit_date = "exit_date") moves
Another set of key functions in the package make basic data manipulation easier.
One thing users of other statistical packages may miss when using R is a
convenient function for determining the mode of a vector. The statamode
function is designed to do just that. statamode works with numeric, character,
and factor data types. It also includes various options for how to deal with a
tie demonstrated below.
vecA <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) statamode(vecA, method = "stata") vecB <- c(1, 1, 1, 3:10) statamode(vecB, method = "last") vecC <- c(1, 1, 1, NA, NA, 5:10) statamode(vecC, method = "last") vecA <- c(LETTERS[1:10]); vecA <- factor(vecA) statamode(vecA, method = "last") vecB <- c("A", "A", "A", LETTERS[3:10]); vecB <- factor(vecB) statamode(vecB, method = "last") vecA <- c(LETTERS[1:10]) statamode(vecA, method = "sample") vecB <- c("A", "A", "A", LETTERS[3:10]) statamode(vecB, method = "stata") vecC <- c("A", "A", "A", NA, NA, LETTERS[5:10]) statamode(vecC, method = "stata")
Administrative extracts are rarely clean. remove_char strips a specific
character -- such as the * often used to mark redacted cells -- out of a
column and returns the result, replacing the marker with NA so the column can
be coerced to numeric.
scores <- c(1, 5, 3, 6, "*", 2, 5, "*", "*") remove_char(scores, "*")
Fixed-width identifier codes (school numbers, district codes, FIPS codes) often
lose their leading zeroes when read in as numbers. leading_zero pads them back
to a fixed width.
leading_zero(c(1, 23, 7, 105), digits = 4)
When you summarize arbitrary subsets of data, some subsets may contain only
missing values. Taking max() of such a subset returns -Inf and a warning;
max_mis returns NA instead, which is convenient inside apply or do.call
constructions. nth_max returns the 2nd, 3rd, etc. largest value in a vector.
max_mis(c(7, NA, 3, 2, 0)) max_mis(c(NA, NA, NA, NA)) nth_max(c(1:20, 20:1), n = 2)
Before aggregating unit-record data it is good practice to confirm which
variables uniquely identify a row. isid (named after the Stata command) checks
whether a set of variables forms a unique key.
data(stuatt) isid(stuatt, vars = c("sid")) isid(stuatt, vars = c("sid", "school_year"))
cutoff and thresh help you understand how concentrated a quantity is. After
sorting a vector in descending order, cutoff returns the number of elements
needed to reach a given proportion of the total, while thresh returns the
proportion of the total reached after a given number of elements.
set.seed(442) enrollment <- rpois(100, lambda = 50) cutoff(enrollment, 0.5) # elements needed to reach 50% of the total thresh(enrollment, 10) # proportion of the total in the 10 largest
eeptools provides three new datasets of interest to education researchers. These
datasets are also used in the R Bootcamp for Education Analysts
data("stuatt") head(stuatt)
The stuatt, student attributes, dataset is provided from the
Strategic Data Project Toolkit for Effective Data Use.
This dataset is useful for learning how to clean data in R and how to aggregate
and summarize individual unit-record data into group-level data.
data(stulevel) head(stulevel)
The stulevel dataset is a simulated student-level longitudinal record. It contains
student and school level attributes and is useful for practicing evaluating
longitudinal analyses of student unit-record data.
data("midsch") head(midsch)
The midsch dataset contains an analysis on abnormality in school average
assessment scores. It contains observed and predicted values of aggregated
test scores at the school level for a large midwestern state.
As of version 1.3.0 several older convenience functions are deprecated and will
be removed in a future release. These include defac(), makenum(),
decomma(), cleanTex(), lag_data(), gelmansim(), autoplot.lm(),
crosstabs(), crosstabplot(), profpoly(), and profpoly.data(), along with
the now-defunct theme_dpi*() themes. Where a modern replacement exists it is
named in each function's help page and in NEWS.md; for example, use
as.character() in place of defac(), readr::parse_number() in place of
decomma(), and dplyr::lag() in place of lag_data().
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.