The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
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[@]metanet.ch.

Getting started with psgc

What is the PSGC?

The Philippine Standard Geographic Code (PSGC) is the official list of every geographic area in the Philippines — from the broadest (regions) down to the most granular (barangays). It is published and maintained by the Philippine Statistics Authority (PSA).

Each area is identified by a unique 10-digit code and a geographic level:

Level Description Example
Reg Region Region I – Ilocos Region
Prov Province Ilocos Norte
City City Laoag City
Mun Municipality Bacarra
SubMun Sub-municipality (Metro Manila component cities)
Bgy Barangay Brgy. 1, Laoag City

The PSA releases updated PSGC files several times a year as new cities are chartered, barangays are created, or codes are renumbered. This package bundles 12 releases from Q1 2023 through Q1 2026.


Checking available releases

list_releases()
#>  [1] "Q1_2023"    "Q4_2023"    "April_2024" "Q2_2024"    "Q3_2024"   
#>  [6] "Q4_2024"    "Q1_2025"    "Q2_2025"    "July_2025"  "Q3_2025"   
#> [11] "Q4_2025"    "Q1_2026"
latest_release()
#> [1] "Q1_2026"

By default, every function in this package uses the latest release. You can always pass a specific release name to work with older data.


Getting the full PSGC list

get_psgc() returns the complete list of geographic areas for a given release.

ph <- get_psgc()
nrow(ph)
#> [1] 43768
head(ph)
#>    psgc_code                area_name correspondence_code geographic_level
#> 1 0100000000 Region I (Ilocos Region)           010000000              Reg
#> 2 0102800000             Ilocos Norte           012800000             Prov
#> 3 0102801000                    Adams           012801000              Mun
#> 4 0102801001                    Adams           012801001              Bgy
#> 5 0102802000                  Bacarra           012802000              Mun
#> 6 0102802001                     Bani           012802001              Bgy
#>   old_name city_class income_classification urban_rural island_region
#> 1     <NA>       <NA>                  <NA>        <NA>             L
#> 2     <NA>       <NA>                   1st        <NA>             L
#> 3     <NA>       <NA>                   4th        <NA>             L
#> 4     <NA>       <NA>                  <NA>           R             L
#> 5     <NA>       <NA>                   2nd        <NA>             L
#> 6     <NA>       <NA>                  <NA>           R             L

Filter by geographic level

You do not need to remember the exact code names — plain English works too:

regions <- get_psgc(geographic_level = "Region")
regions[, c("psgc_code", "area_name")]
#>        psgc_code                                               area_name
#> 1     0100000000                                Region I (Ilocos Region)
#> 3398  0200000000                              Region II (Cagayan Valley)
#> 5808  0300000000                              Region III (Central Luzon)
#> 9051  0400000000                                Region IV-A (CALABARZON)
#> 13191 0500000000                                 Region V (Bicol Region)
#> 16783 0600000000                             Region VI (Western Visayas)
#> 20279 0700000000                            Region VII (Central Visayas)
#> 22695 0800000000                           Region VIII (Eastern Visayas)
#> 27210 0900000000                         Region IX (Zamboanga Peninsula)
#> 29621 1000000000                            Region X (Northern Mindanao)
#> 31742 1100000000                                Region XI (Davao Region)
#> 32959 1200000000                               Region XII (SOCCSKSARGEN)
#> 34110 1300000000                           National Capital Region (NCR)
#> 35857 1400000000                  Cordillera Administrative Region (CAR)
#> 37119 1600000000                                    Region XIII (Caraga)
#> 38510 1700000000                                         MIMAROPA Region
#> 40049 1800000000                              Negros Island Region (NIR)
#> 41469 1900000000 Bangsamoro Autonomous Region In Muslim Mindanao (BARMM)
provinces <- get_psgc(geographic_level = "Province")
nrow(provinces)
#> [1] 82
head(provinces[, c("psgc_code", "area_name")])
#>       psgc_code    area_name
#> 2    0102800000 Ilocos Norte
#> 585  0102900000   Ilocos Sur
#> 1388 0103300000     La Union
#> 1985 0105500000   Pangasinan
#> 3399 0200900000      Batanes
#> 3435 0201500000      Cagayan

You can filter for multiple levels at once by passing a vector:

city_mun <- get_psgc(geographic_level = c("City", "Municipality"))
nrow(city_mun)
#> [1] 1642

There is also a convenient shorthand, "city_mun", that does the same thing:

nrow(get_psgc(geographic_level = "city_mun"))
#> [1] 1642

Using a specific release

ph_2023 <- get_psgc("Q1_2023")
nrow(ph_2023)
#> [1] 43784

Looking up a specific code

If you already have a PSGC code and want its details, use psgc_info().

psgc_info("0100000000") # Region I
#>    psgc_code                area_name correspondence_code geographic_level
#> 1 0100000000 Region I (Ilocos Region)           010000000              Reg
#>   old_name city_class income_classification urban_rural island_region release
#> 1     <NA>       <NA>                  <NA>        <NA>             L Q1_2026

You can look up multiple codes at once:

psgc_info(c("0100000000", "0102800000"))
#>    psgc_code                area_name correspondence_code geographic_level
#> 1 0100000000 Region I (Ilocos Region)           010000000              Reg
#> 2 0102800000             Ilocos Norte           012800000             Prov
#>   old_name city_class income_classification urban_rural island_region release
#> 1     <NA>       <NA>                  <NA>        <NA>             L Q1_2026
#> 2     <NA>       <NA>                   1st        <NA>             L Q1_2026

Short codes are accepted — the package pads the rest with trailing zeros, so you only need to provide enough digits to identify the area:

psgc_info("01")      # same as "0100000000" — Region I
#>    psgc_code                area_name correspondence_code geographic_level
#> 1 0100000000 Region I (Ilocos Region)           010000000              Reg
#>   old_name city_class income_classification urban_rural island_region release
#> 1     <NA>       <NA>                  <NA>        <NA>             L Q1_2026
psgc_info("01028")  # same as "0102800000" — Ilocos Norte
#>    psgc_code    area_name correspondence_code geographic_level old_name
#> 2 0102800000 Ilocos Norte           012800000             Prov     <NA>
#>   city_class income_classification urban_rural island_region release
#> 2       <NA>                   1st        <NA>             L Q1_2026

Population data

get_population() returns PSA census figures (2015, 2020, 2024) for all geographic areas in a release.

pop <- get_population()
head(pop)
#>    psgc_code year population
#> 1 0100000000 2015    5026128
#> 2 0100000000 2020    5301139
#> 3 0100000000 2024    5342453
#> 4 0102800000 2015     593081
#> 5 0102800000 2020     609588
#> 6 0102800000 2024     618850

Add area names and geographic levels

Set details = TRUE to include the area name and level alongside the numbers:

pop_detailed <- get_population(details = TRUE)
head(pop_detailed)
#>    psgc_code                area_name geographic_level year population
#> 1 0100000000 Region I (Ilocos Region)              Reg 2015    5026128
#> 2 0100000000 Region I (Ilocos Region)              Reg 2020    5301139
#> 3 0100000000 Region I (Ilocos Region)              Reg 2024    5342453
#> 4 0102800000             Ilocos Norte             Prov 2015     593081
#> 5 0102800000             Ilocos Norte             Prov 2020     609588
#> 6 0102800000             Ilocos Norte             Prov 2024     618850

Filter by geographic level

Same aliases as get_psgc() work here too:

region_pop <- get_population(geographic_level = "Region", details = TRUE)
region_pop
#>     psgc_code                                               area_name
#> 1  0100000000                                Region I (Ilocos Region)
#> 2  0100000000                                Region I (Ilocos Region)
#> 3  0100000000                                Region I (Ilocos Region)
#> 4  0200000000                              Region II (Cagayan Valley)
#> 5  0200000000                              Region II (Cagayan Valley)
#> 6  0200000000                              Region II (Cagayan Valley)
#> 7  0300000000                              Region III (Central Luzon)
#> 8  0300000000                              Region III (Central Luzon)
#> 9  0300000000                              Region III (Central Luzon)
#> 10 0400000000                                Region IV-A (CALABARZON)
#> 11 0400000000                                Region IV-A (CALABARZON)
#> 12 0400000000                                Region IV-A (CALABARZON)
#> 13 0500000000                                 Region V (Bicol Region)
#> 14 0500000000                                 Region V (Bicol Region)
#> 15 0500000000                                 Region V (Bicol Region)
#> 16 0600000000                             Region VI (Western Visayas)
#> 17 0600000000                             Region VI (Western Visayas)
#> 18 0600000000                             Region VI (Western Visayas)
#> 19 0700000000                            Region VII (Central Visayas)
#> 20 0700000000                            Region VII (Central Visayas)
#> 21 0700000000                            Region VII (Central Visayas)
#> 22 0800000000                           Region VIII (Eastern Visayas)
#> 23 0800000000                           Region VIII (Eastern Visayas)
#> 24 0800000000                           Region VIII (Eastern Visayas)
#> 25 0900000000                         Region IX (Zamboanga Peninsula)
#> 26 0900000000                         Region IX (Zamboanga Peninsula)
#> 27 0900000000                         Region IX (Zamboanga Peninsula)
#> 28 1000000000                            Region X (Northern Mindanao)
#> 29 1000000000                            Region X (Northern Mindanao)
#> 30 1000000000                            Region X (Northern Mindanao)
#> 31 1100000000                                Region XI (Davao Region)
#> 32 1100000000                                Region XI (Davao Region)
#> 33 1100000000                                Region XI (Davao Region)
#> 34 1200000000                               Region XII (SOCCSKSARGEN)
#> 35 1200000000                               Region XII (SOCCSKSARGEN)
#> 36 1200000000                               Region XII (SOCCSKSARGEN)
#> 37 1300000000                           National Capital Region (NCR)
#> 38 1300000000                           National Capital Region (NCR)
#> 39 1300000000                           National Capital Region (NCR)
#> 40 1400000000                  Cordillera Administrative Region (CAR)
#> 41 1400000000                  Cordillera Administrative Region (CAR)
#> 42 1400000000                  Cordillera Administrative Region (CAR)
#> 43 1600000000                                    Region XIII (Caraga)
#> 44 1600000000                                    Region XIII (Caraga)
#> 45 1600000000                                    Region XIII (Caraga)
#> 46 1700000000                                         MIMAROPA Region
#> 47 1700000000                                         MIMAROPA Region
#> 48 1700000000                                         MIMAROPA Region
#> 49 1800000000                              Negros Island Region (NIR)
#> 50 1900000000 Bangsamoro Autonomous Region In Muslim Mindanao (BARMM)
#> 51 1900000000 Bangsamoro Autonomous Region In Muslim Mindanao (BARMM)
#> 52 1900000000 Bangsamoro Autonomous Region In Muslim Mindanao (BARMM)
#>    geographic_level year population
#> 1               Reg 2015    5026128
#> 2               Reg 2020    5301139
#> 3               Reg 2024    5342453
#> 4               Reg 2015    3451410
#> 5               Reg 2020    3685744
#> 6               Reg 2024    3777608
#> 7               Reg 2015   11218177
#> 8               Reg 2020   12422172
#> 9               Reg 2024   12989074
#> 10              Reg 2015   14414774
#> 11              Reg 2020   16195042
#> 12              Reg 2024   16933234
#> 13              Reg 2015    5796989
#> 14              Reg 2020    6082165
#> 15              Reg 2024    6064426
#> 16              Reg 2015    7536383
#> 17              Reg 2020    7954723
#> 18              Reg 2024    4861911
#> 19              Reg 2015    7396898
#> 20              Reg 2020    8081988
#> 21              Reg 2024    6640875
#> 22              Reg 2015    4440150
#> 23              Reg 2020    4547150
#> 24              Reg 2024    4625929
#> 25              Reg 2015    3629783
#> 26              Reg 2020    3875576
#> 27              Reg 2024    5089934
#> 28              Reg 2015    4689302
#> 29              Reg 2020    5022768
#> 30              Reg 2024    5178326
#> 31              Reg 2015    4893318
#> 32              Reg 2020    5243536
#> 33              Reg 2024    5389422
#> 34              Reg 2015    4545276
#> 35              Reg 2020    4901486
#> 36              Reg 2024    4462776
#> 37              Reg 2015   12877253
#> 38              Reg 2020   13484462
#> 39              Reg 2024   14001751
#> 40              Reg 2015    1722006
#> 41              Reg 2020    1797660
#> 42              Reg 2024    1808985
#> 43              Reg 2015    2596709
#> 44              Reg 2020    2804788
#> 45              Reg 2024    2865196
#> 46              Reg 2015    2963360
#> 47              Reg 2020    3228558
#> 48              Reg 2024    3245446
#> 49              Reg 2024    4904944
#> 50              Reg 2015    3781387
#> 51              Reg 2020    4404288
#> 52              Reg 2024    4545486

Wide format — one row per area

Set wide = TRUE to get each census year as its own column, making it easy to compare figures side by side or feed into a table or chart:

region_pop_wide <- get_population(
  geographic_level = "Region",
  details          = TRUE,
  wide             = TRUE
)
region_pop_wide
#>     psgc_code                                               area_name
#> 1  0100000000                                Region I (Ilocos Region)
#> 2  0200000000                              Region II (Cagayan Valley)
#> 3  0300000000                              Region III (Central Luzon)
#> 4  0400000000                                Region IV-A (CALABARZON)
#> 5  0500000000                                 Region V (Bicol Region)
#> 6  0600000000                             Region VI (Western Visayas)
#> 7  0700000000                            Region VII (Central Visayas)
#> 8  0800000000                           Region VIII (Eastern Visayas)
#> 9  0900000000                         Region IX (Zamboanga Peninsula)
#> 10 1000000000                            Region X (Northern Mindanao)
#> 11 1100000000                                Region XI (Davao Region)
#> 12 1200000000                               Region XII (SOCCSKSARGEN)
#> 13 1300000000                           National Capital Region (NCR)
#> 14 1400000000                  Cordillera Administrative Region (CAR)
#> 15 1600000000                                    Region XIII (Caraga)
#> 16 1700000000                                         MIMAROPA Region
#> 17 1800000000                              Negros Island Region (NIR)
#> 18 1900000000 Bangsamoro Autonomous Region In Muslim Mindanao (BARMM)
#>    geographic_level population_2015 population_2020 population_2024
#> 1               Reg         5026128         5301139         5342453
#> 2               Reg         3451410         3685744         3777608
#> 3               Reg        11218177        12422172        12989074
#> 4               Reg        14414774        16195042        16933234
#> 5               Reg         5796989         6082165         6064426
#> 6               Reg         7536383         7954723         4861911
#> 7               Reg         7396898         8081988         6640875
#> 8               Reg         4440150         4547150         4625929
#> 9               Reg         3629783         3875576         5089934
#> 10              Reg         4689302         5022768         5178326
#> 11              Reg         4893318         5243536         5389422
#> 12              Reg         4545276         4901486         4462776
#> 13              Reg        12877253        13484462        14001751
#> 14              Reg         1722006         1797660         1808985
#> 15              Reg         2596709         2804788         2865196
#> 16              Reg         2963360         3228558         3245446
#> 17              Reg              NA              NA         4904944
#> 18              Reg         3781387         4404288         4545486

Attach population data to the PSGC list

If you want population figures alongside the main PSGC table (rather than as a separate data frame), use include_population_data = TRUE in get_psgc(). This adds a population_data list-column — each cell is a small data frame with population and year:

regions_with_pop <- get_psgc(
  geographic_level       = "Region",
  include_population_data = TRUE
)

# Inspect the population data for the first region
regions_with_pop$population_data[[1]]
#>   population year
#> 1    5026128 2015
#> 2    5301139 2020
#> 3    5342453 2024

Tracking codes across releases

The PSA occasionally renumbers or abolishes areas between releases. map_psgc() traces a code forward to any later release so you can keep longitudinal datasets consistent.

map_psgc("0100000000")  # forward to the latest release
#>              old_code   new_code mapping_type from_release to_release
#> 0100000000 0100000000 0100000000       direct      Q1_2023    Q1_2026
map_psgc("0100000000", to = "Q4_2023")
#>              old_code   new_code mapping_type from_release to_release
#> 0100000000 0100000000 0100000000       direct      Q1_2023    Q4_2023

The mapping_type column tells you what happened to the code:

Type Meaning
direct Code is unchanged
renumbered Code was assigned a new number
split One area was divided into multiple areas
merged Multiple areas were merged into one
abolished Area no longer exists (new_code will be NA)

This is especially useful when joining PSGC-coded survey data from different years — use map_psgc() first to normalise all codes to a single release before merging.

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.