| Title: | NYC Primary Land Use Tax Lot Output (PLUTO) |
|---|---|
| Description: | The New York City Department of City Planning Primary Land Use Tax Lot Output (PLUTO) and MapPLUTO: one record per tax lot with land use, building, zoning, ownership, and assessed value fields, plus lot polygons. Data are stored as a GeoParquet file and accessed via duckplyr. Also includes the PLUTO change file and land use and building class lookup tables. |
| Authors: | Kieran Healy [aut, cre] (ORCID: <https://orcid.org/0000-0001-9114-981X>) |
| Maintainer: | Kieran Healy <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.0.1.9000 |
| Built: | 2026-10-18 18:33:02 UTC |
| Source: | https://github.com/kjhealy/nycpluto |
Returns a duckplyr-backed lazy data frame connected to the PLUTO GeoParquet file bundled with this package: one row for each of the 858,284 tax lots in New York City in PLUTO release 26v2 (August 2026), with 97 attribute fields and the lot polygon from MapPLUTO.
nyc_pluto()nyc_pluto()
Use dplyr verbs to filter, select, and summarise, then call
dplyr::collect() to bring results into R memory. Collect only the
rows and columns you need: the polygons for all lots take over 1 GB in
memory. Use nyc_pluto_to_sf() to turn collected rows into an sf
object.
Sources. Attributes and polygons are from MapPLUTO 26v2, clipped to
the shoreline. The 1,597 lots that are in PLUTO but not in the clipped
MapPLUTO (plutomapid 2, 4, or 5: 1,378 lots not on the tax map and 219
lots wholly under water) come from the PLUTO CSV on NYC Open Data, with
fields that the CSV export reformats (leading zeros, Y/N flags) restored
to DCP's formats. Their geometry is NA.
Condominiums. A condominium appears as one record for its billing lot (lot 7501–7599), with unit, area, and value fields summed over its unit lots. Individual unit lots (1001–6999) are not in PLUTO.
Changes. DCP corrects some source values. dcpedited == "1" marks
lots with a corrected value; nyc_pluto_changes_df lists each change.
Not included. The deprecated sanborn field, the empty notes
field, the source-data date fields (empty in the CSV export), and the
ESRI shape measures.
A duckplyr data frame backed by the GeoParquet file.
Column names are PLUTO's field names in lower case. Codes are as published by DCP. Zero is the usual value for "not available" in area, dimension, and year fields; see each field. The data frame has 98 columns:
Borough: "MN", "BX", "BK", "QN", or "SI"
(character). Marble Hill is "MN" and Rikers Island is "BX", the
boroughs they are legally in.
Tax block (integer).
Tax lot (integer). Condominiums use the billing lot, 7501–7599.
Community district (integer): borough code followed by the
district number, e.g. 101, 412. Joint interest areas (large parks
and airports outside any district) are 164 Central Park, 226 Van
Cortlandt Park, 227 Bronx Park, 228 Pelham Bay Park, 355
Prospect Park, 356, 484, and 595 Gateway National Recreation
Area, 480 LaGuardia Airport, 481 Flushing Meadows Corona Park,
482 Forest Park, and 483 JFK Airport. Marble Hill is in districts
207/208 and Rikers Island in 401, the districts that serve
them.
2020 census tract: borough code and six-digit tract,
e.g. "4062600" (character).
2020 census block: borough code, six-digit tract, and four-digit block (character).
2010 census tract, e.g. "203.01", "23"
(character).
2010 census block, four digits with an optional letter suffix (character).
School district, two digits (character).
City council district, 1–51 (integer).
A ZIP code valid for one of the lot's addresses
(character). NA if the lot has no house number.
Fire company: E (engine), L (ladder), or Q
(squad) and a three-digit number, e.g. "E005" (character).
Police precinct (integer).
Health center district (integer).
Health area, with an implied decimal point after the first two digits (integer).
Borough code of the sanitation district (character).
Sanitation district, two digits (character).
Sanitation district subsection (character).
Address of the lot from DOF; the low house number when there is a range (character).
Zoning district covering the largest share of the
lot, e.g. "R6", "C4-4A", "M1-1", "PARK" (character).
Further zoning districts covering at least 10% of the lot, in order of share (character).
Commercial overlays (C1 or C2 districts within residential districts), in order of share (character).
Special purpose districts covering at
least 10% of the lot, in order of share, e.g. "MiD" (Midtown),
"DB" (Downtown Brooklyn) (character). See appendix A of the PLUTO
data dictionary.
Limited height district, e.g. "LH-1"
(character).
"Y" if the lot is split between zoning districts,
commercial overlays, or special districts, otherwise "N"
(character).
Building class (character). See nyc_pluto_bldg_class_df.
Land use category, "01"–"11" (character). See
nyc_pluto_land_use_df.
Number of easements on the lot (integer).
Type of ownership: "C" city, "M" mixed city and
private, "O" other public (authority, state, or federal), "P"
private, "X" fully tax-exempt; NA unknown, usually private
(character).
Owner name; names of public owners are normalized (character).
Lot area in square feet (integer).
Total building floor area in square feet, gross except
for condominiums, whose areas are net (integer). Zero means not
available when numbldgs > 0, and not applicable otherwise.
Floor
area in square feet allocated to commercial, residential, office,
retail, garage, storage, factory, and other uses (integer). Zero
can mean not available or not applicable. Office through other areas
are not available for one- to three-family buildings. The parts do
not always sum to bldgarea.
Source of bldgarea: "0" not available, "2" DOF
Property Tax System, "4" vacant lot with no buildings (area 0),
"5" calculated from building dimensions and floors (primary
building only), "7" DOF Mass Appraisal System (character).
Number of buildings on the lot (integer).
Number of floors of the tallest building, including
partial floors (double). NA with numbldgs > 0 means not
available.
Number of residential units (integer).
Number of residential and non-residential units (integer).
Lot frontage and depth in feet (double).
Building frontage and depth in feet (double).
Extension: "E" extension, "G" garage, "EG" both,
"N" none; NA unknown (character).
Proximity to neighbouring buildings: "0" not
available, "1" detached, "2" semi-attached, "3" attached
(character).
"Y" if the lot is irregularly shaped, otherwise
"N" (character).
Lot type: "0" unknown, "1" block assemblage, "2"
waterfront, "3" corner, "4" through, "5" inside, "6"
interior (no frontage), "7" island, "8" alley, "9" submerged
(character).
Basement: "0" none, "1" above-grade full, "2"
below-grade full, "3" above-grade partial, "4" below-grade
partial, "5" unknown (character).
Assessed land value in dollars (double).
Assessed total value in dollars (double).
Exempt total value in dollars (double).
Year the building was completed (integer). Accurate to the decade, not always the year. Zero means unknown.
Years of the second most recent and most recent alterations (integer). Zero if none.
Name of the historic district the lot is in (character).
"INDIVIDUAL LANDMARK", "INTERIOR LANDMARK", or
"INDIVIDUAL AND INTERIOR LANDMARK" (character).
Built floor area ratio: bldgarea / lotarea
(double).
Maximum allowable residential, commercial, and community facility floor area ratios under the lot's zoning (double).
Borough code: 1 Manhattan, 2 Bronx, 3 Brooklyn, 4 Queens, 5 Staten Island (integer).
Borough-block-lot, 10 digits (character). Unique.
Condominium number, unique within a borough (integer).
2010 census tract as four digits plus a two-digit
suffix if any, e.g. "020301", "0023" (character).
Approximate lot location in feet, EPSG:2263 (integer).
DCP zoning map number (character).
"Y" if the lot is on the border of two or more zoning
maps (character).
DOF paper tax map volume (character). No longer updated.
(E) designation number for environmental requirements (character).
Apportionment BBL: the lot's BBL before a merger, split, or condominium conversion since 1984 (character).
Date of the apportionment (Date).
DCP's file indicator (character): "1" in PLUTO
and both MapPLUTO versions; "2" in PLUTO only; "3" in both
MapPLUTO versions but not PLUTO; "4" in PLUTO and the
water-included MapPLUTO but not the clipped version (entirely under
water); "5" in the water-included MapPLUTO only (under water). All
five values occur in this release; lots with "2", "4", or "5"
have no polygon.
"1" if part of the lot is in the 1% annual chance
floodplain in FEMA's 2007 Flood Insurance Rate Map (character).
"1" if part of the lot is in the 1% annual
chance floodplain in FEMA's 2015 Preliminary Flood Insurance Rate Map
(character).
PLUTO release, "26v2" (character).
"1" if DCP changed any field value for the lot
(character). See nyc_pluto_changes_df.
Approximate lot location in decimal degrees, WGS84 (double).
"1" if Mandatory
Inclusionary Housing option 1, 2, 3 (deep affordability), or 4
(workforce) applies to the lot (character).
Transit zone, which governs residential parking
requirements, e.g. "Manhattan Core", "Inner Transit Zone",
"Beyond the Greater Transit Zone" (character).
Maximum allowable residential floor area ratio for affordable housing (double).
Maximum allowable manufacturing floor area ratio (double).
Lot polygon, MultiPolygon in EPSG:2263, as WKB (raw
vector, list column after collecting). NA for lots not in the
clipped MapPLUTO.
NYC Department of City Planning, PLUTO and MapPLUTO 26v2, https://www.nyc.gov/content/planning/pages/resources/datasets/mappluto-pluto-change; NYC Open Data, https://data.cityofnewyork.us/d/64uk-42ks.
## Not run: library(dplyr) # Residential units by borough nyc_pluto() |> summarise(units = sum(unitsres, na.rm = TRUE), .by = borough) |> collect() # Lot polygons for one block nyc_pluto() |> filter(borough == "MN", block == 1376) |> collect() |> nyc_pluto_to_sf() ## End(Not run)## Not run: library(dplyr) # Residential units by borough nyc_pluto() |> summarise(units = sum(unitsres, na.rm = TRUE), .by = borough) |> collect() # Lot polygons for one block nyc_pluto() |> filter(borough == "MN", block == 1376) |> collect() |> nyc_pluto_to_sf() ## End(Not run)
Building class codes used in PLUTO, with their descriptions and land use categories.
nyc_pluto_bldg_class_dfnyc_pluto_bldg_class_df
nyc_pluto_bldg_class_dfA tibble with 225 rows and 4 columns:
Two-character building class code (character). Joins
to bldgclass in nyc_pluto(). The first character is the general
class: for example A one-family dwellings, B two-family, C
walk-up apartments, D elevator apartments, R condominiums, V
vacant land.
Description of the class (character).
Land use category the class is assigned to,
"01"–"11" (character). See nyc_pluto_land_use_df. NA for
unassigned classes.
Source of the code: "DOF" for Department of Finance
building classes, "DCP" for classes the Department of City
Planning adds in PLUTO (character).
DCP assigns its own classes to condominium billing lots whose units have
mixed classes: RC (mixed commercial), RD (mixed residential), RM
(residential and commercial), RI (commercial and industrial), RX
(residential, commercial, and industrial), and RZ (residential and
industrial). It also assigns Q0 to vacant lots mapped as parks and
QG to vacant lots with community gardens.
A few codes in PLUTO 26v2 are not defined in either dictionary: CB,
CC, DB, DC, VC, and VG (118 lots).
Kieran Healy
NYC Department of Finance, Annualized Calendar Sales Update data dictionary, https://data.cityofnewyork.us/d/w2pb-icbu; NYC Department of City Planning, PLUTO data dictionary 26v2, appendices C and D.
Corrections that the Department of City Planning (DCP) applies to source agency values when building PLUTO. One row per lot and field changed. The changes listed are those in effect in release 26v2, including programmatic changes first made in earlier releases.
nyc_pluto_changes_dfnyc_pluto_changes_df
nyc_pluto_changes_dfA tibble with 42,955 rows and 7 columns:
Borough-block-lot of the changed lot, 10 digits
(character). Joins to bbl in nyc_pluto().
PLUTO field changed, e.g. "yearbuilt", "ownername",
"lotarea" (character).
Original value from the source agency (character).
Value in PLUTO after the change (character).
Kind of change (integer). DCP's metadata does not define
the codes; the reasons recorded with them indicate 1 programmatic
changes (e.g. normalized owner names, zero lot areas), 2 research
changes (e.g. LPC year built, Property Tax System errors), and 3
user-reported changes.
Reason for the change, e.g. "LPC year built",
"Normalized owner name", "Zero lot area", "PTS error - units"
(character).
For programmatic changes, the PLUTO release in which
the change was introduced, e.g. "20v1" (character).
The most common changes are year built replaced by the Landmarks
Preservation Commission's date for about 26,000 buildings in historic
districts, normalized names of public owners, and zero lot areas
replaced by the area of the lot on the Digital Tax Map. Lots with any
change have dcpedited == "1" in nyc_pluto().
Kieran Healy
NYC Open Data, PLUTO Change File, https://data.cityofnewyork.us/d/qt5r-nqxp
The 11 land use categories that the Department of City Planning assigns to tax lots in PLUTO, with the building classes in each.
nyc_pluto_land_use_dfnyc_pluto_land_use_df
nyc_pluto_land_use_dfA tibble with 11 rows and 3 columns:
Land use code, "01"–"11" (character). Joins to
landuse in nyc_pluto().
Land use category, e.g.
"One & Two Family Buildings", "Vacant Land" (character).
Building classes assigned to the category
(character). A trailing * means every class with that first letter,
e.g. "A*" is all one-family dwellings.
Building classes R0, RT, Y5, Z7, and Z9 are not assigned to a land use
category, so lots with those classes have no landuse.
Kieran Healy
NYC Department of City Planning, PLUTO data dictionary 26v2, appendix D.
Returns the path to the GeoParquet file bundled with this package. Useful for direct access via arrow, DuckDB, or GDAL.
nyc_pluto_path()nyc_pluto_path()
A character string file path.
nyc_pluto_path()nyc_pluto_path()
Takes a data frame (typically from nyc_pluto() after filtering and
collecting) and converts it to an sf object, with either the lot
polygons or points at the lots' approximate locations.
nyc_pluto_to_sf(df, geometry = c("polygon", "point"), crs = 2263)nyc_pluto_to_sf(df, geometry = c("polygon", "point"), crs = 2263)
df |
A data frame with a |
geometry |
|
crs |
Target CRS. Default is EPSG:2263 (NAD83 / New York Long Island, ftUS). |
An sf object. Rows without the requested geometry are dropped, with a message.
## Not run: library(dplyr) nyc_pluto() |> filter(borough == "BK", cd == 306) |> collect() |> nyc_pluto_to_sf() nyc_pluto() |> filter(landuse == "03") |> select(bbl, unitsres, latitude, longitude) |> collect() |> nyc_pluto_to_sf(geometry = "point") ## End(Not run)## Not run: library(dplyr) nyc_pluto() |> filter(borough == "BK", cd == 306) |> collect() |> nyc_pluto_to_sf() nyc_pluto() |> filter(landuse == "03") |> select(bbl, unitsres, latitude, longitude) |> collect() |> nyc_pluto_to_sf(geometry = "point") ## End(Not run)