The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

knitr::opts_chunk$set(warning = FALSE, message = FALSE)
library(nycOpenData)
library(ggplot2)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

Introduction

New York City serves a large and diverse population, including individuals and families who experience housing instability and may rely on homeless shelters for temporary support. Pets serve many important role in people’s lives, and understanding pet ownership among shelter entrants helps inform shelter policy, access to services, and resource planning.

The Local Law 97 of 2021 – Pets in Shelter Report provides quarterly survey data on the types of pets owned by people entering New York City homeless shelters.This dataset was recently added to NYC Open Data and made publicly available on October 14, 2025. These data are published through NYC Open Data and are available here.

The nycOpenData package provides a streamlined interface for accessing New York City’s open data resources directly in R. By using the nyc_locallaw97_shelter_pets() function, we can retrieve the most recent quarterly shelter pet data and explore trends in pet ownership across time using familiar data analysis tools.

Pulling a Small Sample

To start, we’ll pull a small sample of the data to get a sense of what it looks like. By default, the function retrieves the 10,000 most recent requests, so we’ll adjust this and only load the latest 3 by using limit = 3.

small_sample <- nyc_locallaw97_shelter_pets(limit = 3)
small_sample
#> # A tibble: 3 Ă— 24
#>   date_year date_quarter total_applicants had_pet client_borough_of_entry_bronx
#>   <chr>     <chr>        <chr>            <chr>   <chr>                        
#> 1 2026      Qtr 1        12062            16      16                           
#> 2 2025      Qtr 4        12727            10      10                           
#> 3 2025      Qtr 3        11704            10      10                           
#> # ℹ 19 more variables: client_borough_of_entry <chr>,
#> #   client_borough_of_entry_1 <chr>, clients_who_would_have_entered <chr>,
#> #   clients_choosing_to_forego <chr>, chose_to_forego_shelter_for <chr>,
#> #   clients_who_intend_to_regain <chr>, number_of_dogs <chr>,
#> #   number_of_cats <chr>, number_of_birds <chr>, number_of_small_mammals <chr>,
#> #   number_of_reptiles_small <chr>, number_of_fish <chr>,
#> #   did_not_report_pet_type <chr>, pet_s_placed_with_foster <chr>, …

# Seeing what columns are in the dataset
colnames(small_sample)
#>  [1] "date_year"                      "date_quarter"                  
#>  [3] "total_applicants"               "had_pet"                       
#>  [5] "client_borough_of_entry_bronx"  "client_borough_of_entry"       
#>  [7] "client_borough_of_entry_1"      "clients_who_would_have_entered"
#>  [9] "clients_choosing_to_forego"     "chose_to_forego_shelter_for"   
#> [11] "clients_who_intend_to_regain"   "number_of_dogs"                
#> [13] "number_of_cats"                 "number_of_birds"               
#> [15] "number_of_small_mammals"        "number_of_reptiles_small"      
#> [17] "number_of_fish"                 "did_not_report_pet_type"       
#> [19] "pet_s_placed_with_foster"       "pet_s_surrendered_to_animal"   
#> [21] "pet_s_placed_with_family"       "pet_s_placed_with_friend"      
#> [23] "pet_s_placed_with_other"        "pet_s_placed_with_non_profit"

Fantastic! We successfully pulled the Local Law 97 of 2021-Pets in Shelter Report data from the NYC Open Data Portal using the nyc_locallaw97_shelter_pets() function.

Let’s now look at an example using the most recent 3 quarters of data. The nyc_locallaw97_shelter_pets() function allows users to filter based on any of the columns in the dataset. To apply filters, we add filters = list() and specify the desired conditions. From our earlier inspection of the column names, we know that there are columns such as date_year and date_quarter that can be used to filter the data by time period.


recent_quarters <- nyc_locallaw97_shelter_pets(
  limit = 3,
  filters = list(date_year = 2024))

recent_quarters
#> # A tibble: 3 Ă— 24
#>   date_year date_quarter total_applicants had_pet client_borough_of_entry_bronx
#>   <chr>     <chr>        <chr>            <chr>   <chr>                        
#> 1 2024      Qtr 4        11874            4       4                            
#> 2 2024      Qtr 3        11901            2       2                            
#> 3 2024      Qtr 2        12274            4       4                            
#> # ℹ 19 more variables: client_borough_of_entry <chr>,
#> #   client_borough_of_entry_1 <chr>, clients_who_would_have_entered <chr>,
#> #   clients_choosing_to_forego <chr>, chose_to_forego_shelter_for <chr>,
#> #   clients_who_intend_to_regain <chr>, number_of_dogs <chr>,
#> #   number_of_cats <chr>, number_of_birds <chr>, number_of_small_mammals <chr>,
#> #   number_of_reptiles_small <chr>, number_of_fish <chr>,
#> #   did_not_report_pet_type <chr>, pet_s_placed_with_foster <chr>, …

# Checking to see the filtering worked
unique(recent_quarters$date_year)
#> [1] "2024"

Success! From calling the filtered dataset, we see that only three rows of data are returned, and the unique() check confirms that all observations come from the specified year.

One of the strongest qualities of this function is its ability to filter based on multiple columns at once. Let’s put everything together and create a dataset containing all available quarterly records for a selected year where shelter entrants reported having pets.

# Creating the dataset
pets_filtered <- nyc_locallaw97_shelter_pets(
  limit = 20,
  filters = list(
    date_year = 2024,
    had_pet = 1))

# Calling head of our new dataset
head(pets_filtered)
#> # A tibble: 0 Ă— 0

# Quick check to make sure our filtering worked
nrow(pets_filtered)
#> [1] 0
unique(pets_filtered$date_year)
#> NULL
unique(pets_filtered$had_pet)
#> NULL

We successfully created a dataset containing the most recent quarterly records for a selected year in which shelter entrants reported having pets.

Mini analysis

Now that we’ve successfully pulled the data and have it in R, let’s do a quick mini analysis to look at how the number of shelter entrants who reported having pets changes over time.

To do this, we’ll create a simple bar chart showing the number of applicants with pets in each year.


pets <- nyc_locallaw97_shelter_pets(limit = 100)
pets$had_pet <- as.numeric(pets$had_pet)

# Summarize by year
pet_by_year <- pets %>%
  group_by(date_year) %>%
  summarize(applicants_with_pets = sum(had_pet, na.rm = TRUE))

# Plot
ggplot(pet_by_year, aes(x = date_year, y = applicants_with_pets)) +
  geom_col(fill = "darkseagreen") +
  theme_minimal() +
  labs(
    title = "Shelter Applicants With Pets by Year (NYC)",
    subtitle = "Local Law 97 - Pets in Shelter Report",
    x = "Year",
    y = "Number of Applicants With Pets"
  )
Bar chart showing the number of shelter applicants with pets by year.

Bar chart showing the number of shelter applicants with pets by year.

This graph shows how the number of shelter entrants reporting pets changes across years, which can help highlight broader trends and guide planning for pet-related shelter resources.

Summary

The nycOpenData package serves as a robust interface for the NYC Open Data portal, streamlining the path from raw city APIs to actionable insights. By abstracting the complexities of data acquisition—such as pagination, type-casting, and complex filtering—it allows users to focus on analysis rather than data engineering.

As demonstrated in this vignette, the package provides a seamless workflow for targeted data retrieval, automated filtering, and rapid visualization.

How to Cite

If you use this package for research or educational purposes, please cite it as follows:

Martinez C (2026). nycOpenData: Convenient Access to NYC Open Data API Endpoints. R package version 0.1.6, https://martinezc1.github.io/nycOpenData/.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.