From 261271e2e3f624a343bde2c5162d3d124e667c64 Mon Sep 17 00:00:00 2001 From: KameronLloyd13 Date: Mon, 20 Oct 2025 09:18:01 -0400 Subject: [PATCH 1/5] nfip claims testing / documentation --- R/get_nfip_claims.R | 273 +++++++++++++++++++++++++++++++++----------- 1 file changed, 206 insertions(+), 67 deletions(-) diff --git a/R/get_nfip_claims.R b/R/get_nfip_claims.R index 4c9f87b..2b5ed40 100644 --- a/R/get_nfip_claims.R +++ b/R/get_nfip_claims.R @@ -2,82 +2,149 @@ #' @importFrom magrittr %>% -#' @title Access county-level data on NFIP policies +#' @title Access county-level data on NFIP claims #' @param county_geoids A character vector of five-digit county codes. NULL by default; must be non-NULL if `api = TRUE`. #' @param file_name The name (not the full path) of the Box file containing the raw data. #' @param api If TRUE, query the API. FALSE by default. #' -#' @returns A dataframe comprising county-level data on current NFIP policies +#' @details +#' These data are from: https://www.fema.gov/openfema-data-page/fima-nfip-redacted-claims-v2. +#' Per FEMA: This data set represents more than 2,000,000 NFIP claims transactions. It is +#' derived from the NFIP system of record, staged in the NFIP reporting platform and +#' redacted to protect policy holder personally identifiable information. The +#' dataset includes the 50 states + DC and the following territories: Puerto Rico, +#' US Virgin Islands, and Guam. +#' +#' In order to filter to residential claims, filter out occupancy types 4, 6, 17, 18, 19. +#' +#' Some claims (from multi-unit buildings / condos) are associated with multiple insured units. +#' When calculating the number of units covered by a claim, the analyst should use the count_units_insured column. +#' +#' The example below illustrates and example of how the data set can be summarized to show the total +#' number of residential claims submitted in two different counties, as well as the total damages +#' and payments in the same time period. +#' +#' @returns A data frame comprising county-level data on current NFIP policies +#' \describe{ +#' \item{nfip_claim_id}{A unique identifier assigned to the claim record} +#' \item{state_fips}{A two-digit state identifier.} +#' \item{state_abbreviation}{The name of the state.} +#' \item{county_geoid}{A five-digit county identifier.} +#' \item{county_name}{The name of the county.} +#' \item{occupancy_type}{The occupancy type ( 1=single family residence; 2 = 2 to 4 unit residential building; 3 = residential building with more than 4 units; 4 = Non-residential building; 6 = Non Residential - Business; 11 = Single-family residential building with the exception of a mobile home or a single residential unit within a multi unit building; 12 = A residential non-condo building with 2, 3, or 4 units seeking insurance on all units; 13 = A residential non-condo building with 5 or more units seeking insurance on all units; 14 = Residential mobile/manufactured home; 15 = Residential condo association seeking coverage on a building with one or more units; 16 = Single residential unit within a multi-unit building; 17 = Non-residential mobile/manufactured home; 18 = A non-residential building; 19 = a non-residential unit within a multi-unit building)} +#' \item{count_units_insured}{The number of insured units associated with the claim. For example, if a condo submits a claim for the 5-unit building, the count_units_insured will be 5.} +#' \item{cause_of_damage}{The method by which the property/contents were damaged. Note that there may be multiple causes of loss for one claim. (0 : Other causes; 1 : Tidal water overflow; 2 : Stream, river, or lake overflow; 3 : Alluvial fan overflow; 4 : Accumulation of rainfall or snowmelt; 7 : Erosion-demolition; 8 : Erosion-removal; 9 : Earth movement, landslide, land subsidence, sinkholes, etc.; A : Closed basin lake; B : Expedited claim handling process without site inspection; C : Expedited claim handling process follow-up site inspection; D : Expedited claim handling process by Adjusting Process Pilot Program (Remote Adjustment).)} +#' \item{flood_event_name}{The name of the flood event.} +#' \item{building_deductible_code}{The total deductible amount in dollars for buildings, both main and appurtenant that can be applied against a loss (0 : $500; 1 : $1,000; 2 : $2,000; 3 : $3,000; 4 : $4,000; 5 : $5,000; 9 : $750; A : $10,000; B : $15,000; C : $20,000; D : $25,000; E : $50,000; F : $1,250; G : $1,500; H : $200 - Used only in Group Flood Insurance Policies)} +#' \item{contents_deductible_code}{The total deductibel amount in dollars for contents in both main and apartment structures that can be applied against a loss (0 : $500; 1 : $1,000; 2 : $2,000; 3 : $3,000; 4 : $4,000; 5 : $5,000; 9 : $750; A : $10,000; B : $15,000; C : $20,000; D : $25,000; E : $50,000; F : $1,250; G : $1,500; H : $200 - Used only in Group Flood Insurance Policies)} +#' \item{building_property_value}{The actual cash value of the main building in whole dollars as estimated by an adjuster.} +#' \item{contents_property_values}{The actual cash value of the contents in whole dollars as estimated by an adjuster.} +#' \item{contents_replacement_cost}{Estimated cost in whole dollars to replace the contents as reported by the insurer.} +#' \item{building_replacement_cost}{Estimated cost in whole dollars to replace the building as reported by the insurer.} +#' \item{flood_zone_firm_current}{Flood zone derived from the Flood Insurance Rate Map (FIRM) where the insured property is currently located. Refer to FEMA documentation for value descriptions.} +#' \item{total_building_insurance_coverage}{The total insurance amount in whole dollars on the building.} +#' \item{total_contents_insurance_coverage}{The total insurance amount in whole dollars on the contents.} +#' \item{year_of_loss}{The year in which the flood loss occurred.} +#' \item{original_construction_year}{The original year of the construction of the building.} +#' \item{building_damage_amount}{The actual cash value amount of damage to a main property in whole dollars.} +#' \item{net_building_payment_amount}{Net building payment amount made to insured in dollars} +#' \item{contents_damage_amount}{The actual cash value amount of damage to contents in whole dollars} +#' \item{net_contents_payment_amount}{Net contents payment amount made to insured in dollars} +#' \item{net_icc_payment_amount}{Net Increased Cost of Compliance (ICC) payment amount made to insured in dollars.} +#' } #' @export #' #' @examples #' \dontrun{ -#' get_nfip_claims( -#' county_geoids = c("01001", "01003"), -#' api = TRUE) -#' } -get_nfip_claims = function( +#' +#'test <- get_nfip_claims(county_geoids = c("01001", "48201"), +#'file_name = "fima_nfip_claims_2025_09_09.parquet", +#'api = FALSE) %>% +#' filter(year_of_loss >= 2015) %>% ### in the past 10 years +#' filter(!occupancy_type %in% c(4, 6, 17, 18, 19))%>% ### only residential claims +#' group_by(county_geoid)%>% +#' summarise(building_damage = sum(building_damage_amount, na.rm = TRUE), +#' contents_damage = sum(contents_damage_amount, na.rm = TRUE), +#' number_res_claims = n_distinct(nfip_claim_id), +#' building_payment = sum(net_building_payment_amount, na.rm = TRUE), +#' contents_payment = sum(net_contents_payment_amount, na.rm = TRUE), +#' icc_payment = sum(net_icc_payment_amount, na.rm = TRUE)) %>% +#' mutate(total_damages = building_damage + contents_damage, +#' total_payments = building_payment + contents_payment + icc_payment)} + + + get_nfip_claims = function( county_geoids = NULL, file_name = "fima_nfip_claims_2025_06_08.parquet", api = FALSE) { - if (isFALSE(api)) { - inpath = file.path( - get_box_path(), "hazards", "fema", "national-flood-insurance-program", "raw", file_name) + if (isFALSE(api)) { + inpath = file.path( + get_box_path(), "hazards", "fema", "national-flood-insurance-program", "raw", file_name) - if (! file.exists(inpath)) { - stop("The provided `file_name` is invalid.") } + if (! file.exists(inpath)) { + stop("The provided `file_name` is invalid.") } - if (! (stringr::str_detect(inpath, "parquet"))) { + if (! (stringr::str_detect(inpath, "parquet"))) { - convert_delimited_to_parquet( - inpath = inpath, - delimit_character = ",", - dataset = "nfip_claims") } + convert_delimited_to_parquet( + inpath = inpath, + delimit_character = ",", + dataset = "nfip_claims") } - df1a = arrow::read_parquet(file = inpath) %>% - janitor::clean_names() + df1a = arrow::read_parquet(file = inpath) %>% + janitor::clean_names() - } else { - if (is.null(county_geoids)) { - stop("No `county_geoids` value was supplied; for querying the API, you must supply this argument.") - county_geoids = tidycensus::fips_codes %>% - dplyr::mutate(county_geoid = stringr::str_c(state_code, county_code)) %>% - dplyr::distinct(county_geoid) %>% - dplyr::pull(county_geoid) + } else { + if (is.null(county_geoids)) { + stop("No `county_geoids` value was supplied; for querying the API, you must supply this argument.") + county_geoids = tidycensus::fips_codes %>% + dplyr::mutate(county_geoid = stringr::str_c(state_code, county_code)) %>% + dplyr::distinct(county_geoid) %>% + dplyr::pull(county_geoid) + } + + df1a = purrr::map_dfr( + county_geoids, + ~ rfema::open_fema( + data_set = "fimanfippolicies", + filters = list(countyCode = .x), + ask_before_call = FALSE) %>% + janitor::clean_names()) } - df1a = purrr::map_dfr( - county_geoids, - ~ rfema::open_fema( - data_set = "fimanfippolicies", - filters = list(countyCode = .x), - ask_before_call = FALSE) %>% - janitor::clean_names()) - } - - df1b = df1a %>% - dplyr::mutate(county_geoid = stringr::str_sub(census_tract, 1, 5)) %>% - {if (!is.null(county_geoids)) dplyr::filter(., county_geoid %in% county_geoids) else . } %>% - dplyr::left_join( - tidycensus::fips_codes %>% - dplyr::select(state_fips = state_code, state_abb = state, county_fips = county_code, county_name = county) %>% - dplyr::mutate(county_geoid = stringr::str_c(state_fips, county_fips)), - by = c("county_geoid")) + df1b = df1a |> + tidytable::mutate(county_geoid = tidytable::if_else( + !is.na(county_code), + county_code, + stringr::str_sub(census_tract, 1, 5) ### taking county_code if it exists, if not extract from census_tract + )) + + if (!is.null(county_geoids)) { + df1b = df1b |> + tidytable::filter(county_geoid %in% county_geoids) + } ### filtering to only the selected county_geoids + + df1c = df1b |> + tidytable::left_join( + tidycensus::fips_codes |> + tidytable::select(state_fips = state_code, state_abb = state, county_fips = county_code, county_name = county) |> + tidytable::mutate(county_geoid = stringr::str_c(state_fips, county_fips)), + by = c("county_geoid")) |> + tidytable::mutate(id = tidytable::map_chr(id, function(x) paste0(format(x), collapse = ""))) ### converting the unique IDs to character values ## to save space: rm(df1a) - result = df1b %>% - dplyr::select( - nfip_policy_id = id, + result = df1c |> + dplyr::transmute( + nfip_claim_id = id, state_fips, state_abbreviation = state, county_geoid, county_name, occupancy_type, - count_units_insured = policy_count, ## if a condo, the number of units is stored separately (see below) - count_units_condo_insured = number_of_units, ## "the number of residential AND NONRESIDENTIAL units covered by the conominium master policy" + count_units_insured = policy_count, ## number of insured units associated with the claim cause_of_damage, flood_event_name = flood_event, building_deductible_code, @@ -90,29 +157,101 @@ get_nfip_claims = function( total_building_insurance_coverage, total_contents_insurance_coverage, year_of_loss, - dplyr::matches("amount")) + original_construction_year = lubridate::year(original_construction_date), + building_damage_amount, + contents_damage_amount, + net_building_payment_amount, + net_contents_payment_amount, + net_icc_payment_amount) - ## NEED TO ADDRESS THE TWO COUNT VARIABLES SO THAT EACH RECORD REFLECTS A SINGLE CLAIM - ## OR HAS A SINGLE VARIABLE DENOTING THE NUMBER OF CLAIMS IT ENCOMPASSES - # result %>% - # dplyr::select(dplyr::matches("count")) %>% - # dplyr::count(count_units_condo_insured, count_units_insured, sort = TRUE) - message(" -These data are from: https://www.fema.gov/openfema-data-page/fima-nfip-redacted-policies-v2. -Per FEMA: This dataset represents more than 80,000,000 policy transactions. It is + message("These data are from: https://www.fema.gov/openfema-data-page/fima-nfip-redacted-claims-v2. +Per FEMA: This dataset represents more than 2,000,000 claims transactions. It is derived from the NFIP system of record, staged in the NFIP reporting platform and -redacted to protect policy holder personally identifiable information.") +redacted to protect policy holder personally identifiable information." - return(result) +) } - utils::globalVariables(c( - "census_tract", "county_geoid", "state_code", "state", "county_code", "county", - "state_fips", "county_fips", "id", "state_abb", "county_name", "policy_cost", - "policy_count", "building_deductible_code", "building_property_value", "cause_of_damage", - "contents_deductible_code", "contents_property_value", "contents_replacement_cost", - "count_units_condo_insured", "count_units_insured", "flood_event", "flood_zone_current", - "number_of_units", "total_building_insurance_coverage", "total_contents_insurance_coverage", - "year_of_loss")) + "building_deductible_code", "building_property_value", + "building_replacement_cost", "cause_of_damage", "census_tract", + "contents_deductible_code", "contents_damage_amount", + "contents_property_value", "contents_replacement_cost", + "county", "county_code", "county_fips", "county_geoid", + "county_name", "flood_event", "flood_zone_current", + "id", "net_building_payment_amount", "net_contents_payment_amount", + "net_icc_payment_amount", "occupancy_type", "original_construction_date", + "original_construction_year", "policy_count", "state", "state_abb", + "state_abbreviation", "state_code", "state_fips", "total_building_insurance_coverage", + "total_contents_insurance_coverage", "year_of_loss", "building_damage_amount" + )) + +# inpath_default = file.path( +# get_box_path(), "hazards", "fema", "national-flood-insurance-program", "intermediate", "fima_nfip_claims_2025_09_09_cleaned.parquet") +# +# write_parquet(result, inpath_default) + +# +# if(isFALSE(api)) { +# +# cleaned_path <- file.path( +# get_box_path(), "hazards", "fema", "national-flood-insurance-program", "final", "fima_nfip_claims_2025_09_09_cleaned.parquet") +# +# if(file.exists(cleaned_path)) { +# +# df1 = arrow::read_parquet(file = cleaned_path) %>% +# janitor::clean_names() +# +# if(!is.null(county_geoids)) { +# df1 = df1 |> +# dplyr::filter(county_geoid %in% county_geoids) +# } +# +# message("These data are from: https://www.fema.gov/openfema-data-page/fima-nfip-redacted-claims-v2. +# Per FEMA: This dataset represents more than 2,000,000 claims transactions. It is +# derived from the NFIP system of record, staged in the NFIP reporting platform and +# redacted to protect policy holder personally identifiable information.") +# +# return(df1) +# +# } else { +# +# inpath = file.path( +# get_box_path(), "hazards", "fema", "national-flood-insurance-program", "raw", file_name) +# +# if (! file.exists(inpath)) { +# stop("The provided `file_name` is invalid.") } +# +# if (! (stringr::str_detect(inpath, "parquet"))) { +# +# convert_delimited_to_parquet( +# inpath = inpath, +# delimit_character = ",", +# dataset = "nfip_claims") } +# +# df1 = arrow::read_parquet(file = inpath) %>% +# janitor::clean_names() +# +# } +# } +# +# else { +# if (is.null(county_geoids)) { +# stop("No `county_geoids` value was supplied; for querying the API, you must supply this argument.") +# county_geoids = tidycensus::fips_codes %>% +# dplyr::mutate(county_geoid = stringr::str_c(state_code, county_code)) %>% +# dplyr::distinct(county_geoid) %>% +# dplyr::pull(county_geoid) +# } +# +# df1a = purrr::map_dfr( +# county_geoids, +# ~ rfema::open_fema( +# data_set = "fimanfippolicies", +# filters = list(countyCode = .x), +# ask_before_call = FALSE) %>% +# janitor::clean_names()) +# } +# +# From ea966cd211183e5c6be86512abc0a1a4d65e5afb Mon Sep 17 00:00:00 2001 From: wcurrangroome Date: Mon, 20 Oct 2025 14:46:53 -0400 Subject: [PATCH 2/5] minor adjustments to get_nfip_claims --- R/get_hazard_mitigation_assistance.R | 2 +- R/get_nfip_claims.R | 308 ++++++++++----------------- R/get_public_assistance.R | 15 +- man/get_nfip_claims.Rd | 60 +++++- man/get_public_assistance.Rd | 11 +- 5 files changed, 187 insertions(+), 209 deletions(-) diff --git a/R/get_hazard_mitigation_assistance.R b/R/get_hazard_mitigation_assistance.R index 586cee5..935cffb 100644 --- a/R/get_hazard_mitigation_assistance.R +++ b/R/get_hazard_mitigation_assistance.R @@ -431,4 +431,4 @@ utils::globalVariables(c( "project_counties", "hma_project00", "initial_obligation_amount", "project_counties_multiple_flag", "project_fiscal_year", "project_id", "project_identifier", "project_program_area", "selection_federal_share_amount", "selection_federal_share_amount_split", "status", - "subapplicant_state", "subapplicant_state_abbreviation")) + "subapplicant_state", "subapplicant_state_abbreviation", "selection_status")) diff --git a/R/get_nfip_claims.R b/R/get_nfip_claims.R index 2b5ed40..05d7ae5 100644 --- a/R/get_nfip_claims.R +++ b/R/get_nfip_claims.R @@ -1,5 +1,3 @@ -# Author: Will Curran-Groome - #' @importFrom magrittr %>% #' @title Access county-level data on NFIP claims @@ -26,153 +24,146 @@ #' #' @returns A data frame comprising county-level data on current NFIP policies #' \describe{ -#' \item{nfip_claim_id}{A unique identifier assigned to the claim record} -#' \item{state_fips}{A two-digit state identifier.} -#' \item{state_abbreviation}{The name of the state.} -#' \item{county_geoid}{A five-digit county identifier.} -#' \item{county_name}{The name of the county.} -#' \item{occupancy_type}{The occupancy type ( 1=single family residence; 2 = 2 to 4 unit residential building; 3 = residential building with more than 4 units; 4 = Non-residential building; 6 = Non Residential - Business; 11 = Single-family residential building with the exception of a mobile home or a single residential unit within a multi unit building; 12 = A residential non-condo building with 2, 3, or 4 units seeking insurance on all units; 13 = A residential non-condo building with 5 or more units seeking insurance on all units; 14 = Residential mobile/manufactured home; 15 = Residential condo association seeking coverage on a building with one or more units; 16 = Single residential unit within a multi-unit building; 17 = Non-residential mobile/manufactured home; 18 = A non-residential building; 19 = a non-residential unit within a multi-unit building)} -#' \item{count_units_insured}{The number of insured units associated with the claim. For example, if a condo submits a claim for the 5-unit building, the count_units_insured will be 5.} -#' \item{cause_of_damage}{The method by which the property/contents were damaged. Note that there may be multiple causes of loss for one claim. (0 : Other causes; 1 : Tidal water overflow; 2 : Stream, river, or lake overflow; 3 : Alluvial fan overflow; 4 : Accumulation of rainfall or snowmelt; 7 : Erosion-demolition; 8 : Erosion-removal; 9 : Earth movement, landslide, land subsidence, sinkholes, etc.; A : Closed basin lake; B : Expedited claim handling process without site inspection; C : Expedited claim handling process follow-up site inspection; D : Expedited claim handling process by Adjusting Process Pilot Program (Remote Adjustment).)} -#' \item{flood_event_name}{The name of the flood event.} -#' \item{building_deductible_code}{The total deductible amount in dollars for buildings, both main and appurtenant that can be applied against a loss (0 : $500; 1 : $1,000; 2 : $2,000; 3 : $3,000; 4 : $4,000; 5 : $5,000; 9 : $750; A : $10,000; B : $15,000; C : $20,000; D : $25,000; E : $50,000; F : $1,250; G : $1,500; H : $200 - Used only in Group Flood Insurance Policies)} -#' \item{contents_deductible_code}{The total deductibel amount in dollars for contents in both main and apartment structures that can be applied against a loss (0 : $500; 1 : $1,000; 2 : $2,000; 3 : $3,000; 4 : $4,000; 5 : $5,000; 9 : $750; A : $10,000; B : $15,000; C : $20,000; D : $25,000; E : $50,000; F : $1,250; G : $1,500; H : $200 - Used only in Group Flood Insurance Policies)} -#' \item{building_property_value}{The actual cash value of the main building in whole dollars as estimated by an adjuster.} -#' \item{contents_property_values}{The actual cash value of the contents in whole dollars as estimated by an adjuster.} -#' \item{contents_replacement_cost}{Estimated cost in whole dollars to replace the contents as reported by the insurer.} -#' \item{building_replacement_cost}{Estimated cost in whole dollars to replace the building as reported by the insurer.} -#' \item{flood_zone_firm_current}{Flood zone derived from the Flood Insurance Rate Map (FIRM) where the insured property is currently located. Refer to FEMA documentation for value descriptions.} -#' \item{total_building_insurance_coverage}{The total insurance amount in whole dollars on the building.} -#' \item{total_contents_insurance_coverage}{The total insurance amount in whole dollars on the contents.} -#' \item{year_of_loss}{The year in which the flood loss occurred.} -#' \item{original_construction_year}{The original year of the construction of the building.} -#' \item{building_damage_amount}{The actual cash value amount of damage to a main property in whole dollars.} -#' \item{net_building_payment_amount}{Net building payment amount made to insured in dollars} -#' \item{contents_damage_amount}{The actual cash value amount of damage to contents in whole dollars} -#' \item{net_contents_payment_amount}{Net contents payment amount made to insured in dollars} -#' \item{net_icc_payment_amount}{Net Increased Cost of Compliance (ICC) payment amount made to insured in dollars.} -#' } +#' \item{state_fips}{A two-digit state identifier.} +#' \item{state_abbreviation}{The name of the state.} +#' \item{county_geoid}{A five-digit county identifier.} +#' \item{county_name}{The name of the county.} +#' \item{year_construction}{The original year of the construction of the building.} +#' \item{year_loss}{The year in which the flood loss occurred.} +#' \item{occupancy_type}{The occupancy type of the primary building associated with the claim.} +#' \item{count_units_insured}{The number of insured units associated with the claim.} +#' \item{deductible_building}{The total deductible for buildings, main and appurtenant.} +#' \item{deductible_contents}{The total deductible for contents.} +#' \item{value_building}{The value of the main building as estimated by an adjuster.} +#' \item{value_contents}{The value of the contents as estimated by an adjuster.} +#' \item{replacement_cost_building}{Estimated cost to replace the building as reported by the insurer.} +#' \item{replacement_cost_contents}{Estimated cost to replace the contents as reported by the insurer.} +#' \item{insurance_coverage_building}{The total insurance amount on the building.} +#' \item{insurance_coverage_contents}{The total insurance amount on the contents.} +#' \item{damage_building}{The amount of damage to a main property.} +#' \item{damage_contents}{The value of damage to contents.} +#' \item{net_payment_building}{Net building payment amount.} +#' \item{net_payment_contents}{Net contents payment amount.} +#' \item{net_payment_increased_compliance}{Net Increased Cost of Compliance (ICC) payment amount.} +#' } #' @export #' #' @examples #' \dontrun{ #' -#'test <- get_nfip_claims(county_geoids = c("01001", "48201"), -#'file_name = "fima_nfip_claims_2025_09_09.parquet", -#'api = FALSE) %>% -#' filter(year_of_loss >= 2015) %>% ### in the past 10 years -#' filter(!occupancy_type %in% c(4, 6, 17, 18, 19))%>% ### only residential claims -#' group_by(county_geoid)%>% -#' summarise(building_damage = sum(building_damage_amount, na.rm = TRUE), -#' contents_damage = sum(contents_damage_amount, na.rm = TRUE), -#' number_res_claims = n_distinct(nfip_claim_id), -#' building_payment = sum(net_building_payment_amount, na.rm = TRUE), -#' contents_payment = sum(net_contents_payment_amount, na.rm = TRUE), -#' icc_payment = sum(net_icc_payment_amount, na.rm = TRUE)) %>% -#' mutate(total_damages = building_damage + contents_damage, -#' total_payments = building_payment + contents_payment + icc_payment)} - - - get_nfip_claims = function( - county_geoids = NULL, - file_name = "fima_nfip_claims_2025_06_08.parquet", - api = FALSE) { - - if (isFALSE(api)) { - inpath = file.path( - get_box_path(), "hazards", "fema", "national-flood-insurance-program", "raw", file_name) - - if (! file.exists(inpath)) { - stop("The provided `file_name` is invalid.") } - - if (! (stringr::str_detect(inpath, "parquet"))) { - - convert_delimited_to_parquet( - inpath = inpath, - delimit_character = ",", - dataset = "nfip_claims") } - - df1a = arrow::read_parquet(file = inpath) %>% - janitor::clean_names() - - } else { - if (is.null(county_geoids)) { - stop("No `county_geoids` value was supplied; for querying the API, you must supply this argument.") - county_geoids = tidycensus::fips_codes %>% - dplyr::mutate(county_geoid = stringr::str_c(state_code, county_code)) %>% - dplyr::distinct(county_geoid) %>% - dplyr::pull(county_geoid) - } - - df1a = purrr::map_dfr( - county_geoids, - ~ rfema::open_fema( - data_set = "fimanfippolicies", - filters = list(countyCode = .x), - ask_before_call = FALSE) %>% - janitor::clean_names()) - } - - df1b = df1a |> - tidytable::mutate(county_geoid = tidytable::if_else( - !is.na(county_code), - county_code, - stringr::str_sub(census_tract, 1, 5) ### taking county_code if it exists, if not extract from census_tract - )) +#' test <- get_nfip_claims(county_geoids = c("01001", "48201")) %>% +#' filter( +#' year_of_loss >= 2015, ### in the past 10 years +#' !occupancy_type %in% c(4, 6, 17, 18, 19)) %>% ### only residential claims +#' summarize( +#' .by = county_geoid, +#' across(matches("payment"), sum, na.rm = TRUE), +#' residential_claims = n_distinct(nfip_claim_id)) +#'} + +get_nfip_claims = function( + county_geoids = NULL, + file_name = "fima_nfip_claims_2025_09_09.parquet", + api = FALSE) { + + ## if reading from disk + if (isFALSE(api)) { + if (is.na(file_name)) stop("If `api = FALSE`, you must provide a `file_name` argument.") + + inpath = file.path( + get_box_path(), "hazards", "fema", "national-flood-insurance-program", "raw", file_name) + + ## check that the cached file exists + if (! file.exists(inpath)) { + stop("The provided `file_name` is invalid.") } + + ## if the cached file isn't a parquet file, convert it to one + if (! (stringr::str_detect(inpath, "parquet"))) { + + convert_delimited_to_parquet( + inpath = inpath, + delimit_character = ",", + dataset = "nfip_claims") } + + ## read the parquet file + df1a = arrow::read_parquet(file = inpath) %>% + janitor::clean_names() + + } else { + + ## if querying the API: + + ## if no county_geoids, throw an error + if (is.null(county_geoids)) { + stop("No `county_geoids` value was supplied; for querying the API, you must supply this argument.") } + + if (length(county_geoids > 10)) { + warning(stringr::str_c( +"These data are very large; given the number of supplied `county_geoids`, anticipate ", +"a slow query. An alternate approach is to download the full dataset and then supply that ", +"filepath to the parameter `file_name`.")) } + + df1a = purrr::map_dfr( + county_geoids, + ~ rfema::open_fema( + data_set = "fimanfippolicies", + filters = list(countyCode = .x), + ask_before_call = FALSE) %>% + janitor::clean_names()) + } + + ## data cleaning: + df1b = df1a |> + tidytable::mutate( + ### taking county_code if it exists, if not extract from census_tract + county_geoid = tidytable::if_else(!is.na(county_code), county_code, stringr::str_sub(census_tract, 1, 5))) if (!is.null(county_geoids)) { df1b = df1b |> - tidytable::filter(county_geoid %in% county_geoids) - } ### filtering to only the selected county_geoids + ### filtering to only the selected county_geoids + tidytable::filter(county_geoid %in% county_geoids) } df1c = df1b |> tidytable::left_join( tidycensus::fips_codes |> - tidytable::select(state_fips = state_code, state_abb = state, county_fips = county_code, county_name = county) |> + tidytable::select( + state_fips = state_code, state_abb = state, county_fips = county_code, + county_name = county) |> tidytable::mutate(county_geoid = stringr::str_c(state_fips, county_fips)), - by = c("county_geoid")) |> - tidytable::mutate(id = tidytable::map_chr(id, function(x) paste0(format(x), collapse = ""))) ### converting the unique IDs to character values - - ## to save space: - rm(df1a) + by = c("county_geoid"), + relationship = "many-to-one") result = df1c |> dplyr::transmute( - nfip_claim_id = id, + #nfip_claim_id = id, state_fips, state_abbreviation = state, county_geoid, county_name, occupancy_type, + year_loss = year_of_loss, + year_construction = lubridate::year(original_construction_date), count_units_insured = policy_count, ## number of insured units associated with the claim - cause_of_damage, - flood_event_name = flood_event, - building_deductible_code, - contents_deductible_code, - building_property_value, - contents_property_value, - contents_replacement_cost, - building_replacement_cost, - flood_zone_firm_current = flood_zone_current, - total_building_insurance_coverage, - total_contents_insurance_coverage, - year_of_loss, - original_construction_year = lubridate::year(original_construction_date), - building_damage_amount, - contents_damage_amount, - net_building_payment_amount, - net_contents_payment_amount, + #cause_of_damage, + #flood_event_name = flood_event, + #flood_zone_firm_current = flood_zone_current, + deductible_building = building_deductible_code, + deductible_contents = contents_deductible_code, + value_building = building_property_value, + value_contents = contents_property_value, + replacement_cost_building = building_replacement_cost, + replacement_cost_contents = contents_replacement_cost, + insurance_coverage_building = total_building_insurance_coverage, + insurance_coverage_contents = total_contents_insurance_coverage, + damage_building = building_damage_amount, + damage_contents = contents_damage_amount, + net_payment_building = net_building_payment_amount, + net_payment_contents = net_contents_payment_amount, net_icc_payment_amount) - - message("These data are from: https://www.fema.gov/openfema-data-page/fima-nfip-redacted-claims-v2. -Per FEMA: This dataset represents more than 2,000,000 claims transactions. It is -derived from the NFIP system of record, staged in the NFIP reporting platform and -redacted to protect policy holder personally identifiable information." - -) - + return(result) } + utils::globalVariables(c( "building_deductible_code", "building_property_value", "building_replacement_cost", "cause_of_damage", "census_tract", @@ -186,72 +177,3 @@ utils::globalVariables(c( "state_abbreviation", "state_code", "state_fips", "total_building_insurance_coverage", "total_contents_insurance_coverage", "year_of_loss", "building_damage_amount" )) - -# inpath_default = file.path( -# get_box_path(), "hazards", "fema", "national-flood-insurance-program", "intermediate", "fima_nfip_claims_2025_09_09_cleaned.parquet") -# -# write_parquet(result, inpath_default) - -# -# if(isFALSE(api)) { -# -# cleaned_path <- file.path( -# get_box_path(), "hazards", "fema", "national-flood-insurance-program", "final", "fima_nfip_claims_2025_09_09_cleaned.parquet") -# -# if(file.exists(cleaned_path)) { -# -# df1 = arrow::read_parquet(file = cleaned_path) %>% -# janitor::clean_names() -# -# if(!is.null(county_geoids)) { -# df1 = df1 |> -# dplyr::filter(county_geoid %in% county_geoids) -# } -# -# message("These data are from: https://www.fema.gov/openfema-data-page/fima-nfip-redacted-claims-v2. -# Per FEMA: This dataset represents more than 2,000,000 claims transactions. It is -# derived from the NFIP system of record, staged in the NFIP reporting platform and -# redacted to protect policy holder personally identifiable information.") -# -# return(df1) -# -# } else { -# -# inpath = file.path( -# get_box_path(), "hazards", "fema", "national-flood-insurance-program", "raw", file_name) -# -# if (! file.exists(inpath)) { -# stop("The provided `file_name` is invalid.") } -# -# if (! (stringr::str_detect(inpath, "parquet"))) { -# -# convert_delimited_to_parquet( -# inpath = inpath, -# delimit_character = ",", -# dataset = "nfip_claims") } -# -# df1 = arrow::read_parquet(file = inpath) %>% -# janitor::clean_names() -# -# } -# } -# -# else { -# if (is.null(county_geoids)) { -# stop("No `county_geoids` value was supplied; for querying the API, you must supply this argument.") -# county_geoids = tidycensus::fips_codes %>% -# dplyr::mutate(county_geoid = stringr::str_c(state_code, county_code)) %>% -# dplyr::distinct(county_geoid) %>% -# dplyr::pull(county_geoid) -# } -# -# df1a = purrr::map_dfr( -# county_geoids, -# ~ rfema::open_fema( -# data_set = "fimanfippolicies", -# filters = list(countyCode = .x), -# ask_before_call = FALSE) %>% -# janitor::clean_names()) -# } -# -# diff --git a/R/get_public_assistance.R b/R/get_public_assistance.R index 928a7da..2dec622 100644 --- a/R/get_public_assistance.R +++ b/R/get_public_assistance.R @@ -1,3 +1,5 @@ +.datatable.aware=TRUE + #' Get FEMA Public Assistance (PA) funding #' #' Project- and county-level data on PA funding over time @@ -28,20 +30,25 @@ #' #' @return A dataframe of project-level funding requests and awards, along with variables that can be aggregated to the county level. #' \describe{ -#' \item{id}{A unique identifier for each project in the raw data. This field is not unique in the returned data due to crosswalking statewide projects to the county level. Refer to the details for additional information} +#' \item{id}{A unique identifier for each project in the raw data. +#' This field is not unique in the returned data due to crosswalking +#' statewide projects to the county level. Refer to the details for additional information} #' \item{state_fips}{A two-digit state identifier.} #' \item{state_name}{The name of the state.} #' \item{state_abbreviation}{The two-character USPS abbreviation for the state.} #' \item{county_fips}{A five-digit county identifier.} #' \item{county_name}{The name of the county.} #' \item{declaration_year}{The year when the authorizing disaster declaration was made.} -#' \item{disaster_number}{The FEMA-created disaster number. This is unique at the disaster-state level; for example, Hurricane Helene has multiple disaster numbers associated with it, one per state that received an associated disaster declaration.} +#' \item{disaster_number}{The FEMA-created disaster number. This is unique +#' at the disaster-state level; for example, Hurricane Helene has multiple +#' disaster numbers associated with it, one per state that received an associated disaster declaration.} #' \item{incident_type}{The type of disaster, e.g., "Hurricane".} #' \item{project_status}{The current status of the funded PA project, e.g., "Active".} #' \item{damage_category_code}{A letter code identifying the category of damages/what funds may be used for.} #' \item{damage_category_description}{A descriptive characteristization of the damage category.} #' \item{pa_federal_funding_obligated}{Obligated federal funding at the project `id` level.} -#' \item{pa_federal_funding_obligated_split}{Obligated federal attributed to the `id`-by-county level. Refer to the details for additional information.} +#' \item{pa_federal_funding_obligated_split}{Obligated federal attributed +#' to the `id`-by-county level. Refer to the details for additional information.} #' } #' @export #' @@ -50,8 +57,6 @@ #' get_public_assistance(state_abbreviations = "NJ") #' } -.datatable.aware=TRUE - get_public_assistance= function( file_path = file.path( get_box_path(), "hazards", "fema", "public-assistance", "raw", diff --git a/man/get_nfip_claims.Rd b/man/get_nfip_claims.Rd index 67d1938..894d6ee 100644 --- a/man/get_nfip_claims.Rd +++ b/man/get_nfip_claims.Rd @@ -2,11 +2,11 @@ % Please edit documentation in R/get_nfip_claims.R \name{get_nfip_claims} \alias{get_nfip_claims} -\title{Access county-level data on NFIP policies} +\title{Access county-level data on NFIP claims} \usage{ get_nfip_claims( county_geoids = NULL, - file_name = "fima_nfip_claims_2025_06_08.parquet", + file_name = "fima_nfip_claims_2025_09_09.parquet", api = FALSE ) } @@ -18,15 +18,61 @@ get_nfip_claims( \item{api}{If TRUE, query the API. FALSE by default.} } \value{ -A dataframe comprising county-level data on current NFIP policies +A data frame comprising county-level data on current NFIP policies +\describe{ +\item{state_fips}{A two-digit state identifier.} +\item{state_abbreviation}{The name of the state.} +\item{county_geoid}{A five-digit county identifier.} +\item{county_name}{The name of the county.} +\item{year_construction}{The original year of the construction of the building.} +\item{year_loss}{The year in which the flood loss occurred.} +\item{occupancy_type}{The occupancy type of the primary building associated with the claim.} +\item{count_units_insured}{The number of insured units associated with the claim.} +\item{deductible_building}{The total deductible for buildings, main and appurtenant.} +\item{deductible_contents}{The total deductible for contents.} +\item{value_building}{The value of the main building as estimated by an adjuster.} +\item{value_contents}{The value of the contents as estimated by an adjuster.} +\item{replacement_cost_building}{Estimated cost to replace the building as reported by the insurer.} +\item{replacement_cost_contents}{Estimated cost to replace the contents as reported by the insurer.} +\item{insurance_coverage_building}{The total insurance amount on the building.} +\item{insurance_coverage_contents}{The total insurance amount on the contents.} +\item{damage_building}{The amount of damage to a main property.} +\item{damage_contents}{The value of damage to contents.} +\item{net_payment_building}{Net building payment amount.} +\item{net_payment_contents}{Net contents payment amount.} +\item{net_payment_increased_compliance}{Net Increased Cost of Compliance (ICC) payment amount.} +} } \description{ -Access county-level data on NFIP policies +Access county-level data on NFIP claims +} +\details{ +These data are from: https://www.fema.gov/openfema-data-page/fima-nfip-redacted-claims-v2. +Per FEMA: This data set represents more than 2,000,000 NFIP claims transactions. It is +derived from the NFIP system of record, staged in the NFIP reporting platform and +redacted to protect policy holder personally identifiable information. The +dataset includes the 50 states + DC and the following territories: Puerto Rico, +US Virgin Islands, and Guam. + +In order to filter to residential claims, filter out occupancy types 4, 6, 17, 18, 19. + +Some claims (from multi-unit buildings / condos) are associated with multiple insured units. +When calculating the number of units covered by a claim, the analyst should use the count_units_insured column. + +The example below illustrates and example of how the data set can be summarized to show the total +number of residential claims submitted in two different counties, as well as the total damages +and payments in the same time period. } \examples{ \dontrun{ -get_nfip_claims( - county_geoids = c("01001", "01003"), - api = TRUE) + +test <- get_nfip_claims(county_geoids = c("01001", "48201")) \%>\% + filter( + year_of_loss >= 2015, ### in the past 10 years + !occupancy_type \%in\% c(4, 6, 17, 18, 19)) \%>\% ### only residential claims + summarize( + .by = county_geoid, + across(matches("payment"), sum, na.rm = TRUE), + residential_claims = n_distinct(nfip_claim_id)) } } diff --git a/man/get_public_assistance.Rd b/man/get_public_assistance.Rd index 773a029..a5f5c8c 100644 --- a/man/get_public_assistance.Rd +++ b/man/get_public_assistance.Rd @@ -18,20 +18,25 @@ get_public_assistance( \value{ A dataframe of project-level funding requests and awards, along with variables that can be aggregated to the county level. \describe{ -\item{id}{A unique identifier for each project in the raw data. This field is not unique in the returned data due to crosswalking statewide projects to the county level. Refer to the details for additional information} +\item{id}{A unique identifier for each project in the raw data. +This field is not unique in the returned data due to crosswalking +statewide projects to the county level. Refer to the details for additional information} \item{state_fips}{A two-digit state identifier.} \item{state_name}{The name of the state.} \item{state_abbreviation}{The two-character USPS abbreviation for the state.} \item{county_fips}{A five-digit county identifier.} \item{county_name}{The name of the county.} \item{declaration_year}{The year when the authorizing disaster declaration was made.} -\item{disaster_number}{The FEMA-created disaster number. This is unique at the disaster-state level; for example, Hurricane Helene has multiple disaster numbers associated with it, one per state that received an associated disaster declaration.} +\item{disaster_number}{The FEMA-created disaster number. This is unique +at the disaster-state level; for example, Hurricane Helene has multiple +disaster numbers associated with it, one per state that received an associated disaster declaration.} \item{incident_type}{The type of disaster, e.g., "Hurricane".} \item{project_status}{The current status of the funded PA project, e.g., "Active".} \item{damage_category_code}{A letter code identifying the category of damages/what funds may be used for.} \item{damage_category_description}{A descriptive characteristization of the damage category.} \item{pa_federal_funding_obligated}{Obligated federal funding at the project \code{id} level.} -\item{pa_federal_funding_obligated_split}{Obligated federal attributed to the \code{id}-by-county level. Refer to the details for additional information.} +\item{pa_federal_funding_obligated_split}{Obligated federal attributed +to the \code{id}-by-county level. Refer to the details for additional information.} } } \description{ From cc9c398f686e6db344481cdae7324dc9ae44779c Mon Sep 17 00:00:00 2001 From: KameronLloyd13 Date: Wed, 22 Oct 2025 11:23:51 -0400 Subject: [PATCH 3/5] updating occupancy categories and making deductible codes numeric --- R/get_nfip_claims.R | 46 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/R/get_nfip_claims.R b/R/get_nfip_claims.R index 05d7ae5..4a730ce 100644 --- a/R/get_nfip_claims.R +++ b/R/get_nfip_claims.R @@ -13,7 +13,7 @@ #' dataset includes the 50 states + DC and the following territories: Puerto Rico, #' US Virgin Islands, and Guam. #' -#' In order to filter to residential claims, filter out occupancy types 4, 6, 17, 18, 19. +#' In order to filter to residential claims, filter out occupancy type: "non-residential". #' #' Some claims (from multi-unit buildings / condos) are associated with multiple insured units. #' When calculating the number of units covered by a claim, the analyst should use the count_units_insured column. @@ -54,7 +54,7 @@ #' test <- get_nfip_claims(county_geoids = c("01001", "48201")) %>% #' filter( #' year_of_loss >= 2015, ### in the past 10 years -#' !occupancy_type %in% c(4, 6, 17, 18, 19)) %>% ### only residential claims +#' !occupancy_type %in% c("non-residential")) %>% ### only residential claims #' summarize( #' .by = county_geoid, #' across(matches("payment"), sum, na.rm = TRUE), @@ -86,7 +86,7 @@ get_nfip_claims = function( dataset = "nfip_claims") } ## read the parquet file - df1a = arrow::read_parquet(file = inpath) %>% + df1a = arrow::read_parquet(file = inpath) |> janitor::clean_names() } else { @@ -108,7 +108,7 @@ get_nfip_claims = function( ~ rfema::open_fema( data_set = "fimanfippolicies", filters = list(countyCode = .x), - ask_before_call = FALSE) %>% + ask_before_call = FALSE) |> janitor::clean_names()) } @@ -140,15 +140,47 @@ get_nfip_claims = function( state_abbreviation = state, county_geoid, county_name, - occupancy_type, + occupancy_type = case_when(occupancy_type %in% c(1, 11, 14) ~ "single family", + occupancy_type %in% c(2, 12) ~ "2-4 units", + occupancy_type %in% c(3, 13, 16, 15) ~ "5+ units", + occupancy_type %in% c(14) ~ "mobile/manufactured home", + occupancy_type %in% c(4, 6, 17, 18, 19) ~ "non-residential"), year_loss = year_of_loss, year_construction = lubridate::year(original_construction_date), count_units_insured = policy_count, ## number of insured units associated with the claim #cause_of_damage, #flood_event_name = flood_event, #flood_zone_firm_current = flood_zone_current, - deductible_building = building_deductible_code, - deductible_contents = contents_deductible_code, + deductible_building = case_when(building_deductible_code == "0" ~ 500, + building_deductible_code == "1" ~ 1000, + building_deductible_code == "2" ~ 2000, + building_deductible_code == "3" ~ 3000, + building_deductible_code == "4" ~ 4000, + building_deductible_code == "5" ~ 5000, + building_deductible_code == "9" ~ 750, + building_deductible_code == "A" ~ 10000, + building_deductible_code == "B" ~ 15000, + building_deductible_code == "C" ~ 20000, + building_deductible_code == "D" ~ 25000, + building_deductible_code == "E" ~ 50000, + building_deductible_code == "F" ~ 1250, + building_deductible_code == "G" ~ 500, + building_deductible_code == "H" ~ 200), + deductible_contents = case_when(contents_deductible_code == "0" ~ 500, + contents_deductible_code == "1" ~ 1000, + contents_deductible_code == "2" ~ 2000, + contents_deductible_code == "3" ~ 3000, + contents_deductible_code == "4" ~ 4000, + contents_deductible_code == "5" ~ 5000, + contents_deductible_code == "9" ~ 750, + contents_deductible_code == "A" ~ 10000, + contents_deductible_code == "B" ~ 15000, + contents_deductible_code == "C" ~ 20000, + contents_deductible_code == "D" ~ 25000, + contents_deductible_code == "E" ~ 50000, + contents_deductible_code == "F" ~ 1250, + contents_deductible_code == "G" ~ 500, + contents_deductible_code == "H" ~ 200), value_building = building_property_value, value_contents = contents_property_value, replacement_cost_building = building_replacement_cost, From 40b749eb9b88ae6c28412e781b93e0e725b1d8f9 Mon Sep 17 00:00:00 2001 From: KameronLloyd13 Date: Fri, 24 Oct 2025 13:58:34 -0400 Subject: [PATCH 4/5] updating occupancy type categories --- R/get_nfip_claims.R | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/R/get_nfip_claims.R b/R/get_nfip_claims.R index 4a730ce..129783a 100644 --- a/R/get_nfip_claims.R +++ b/R/get_nfip_claims.R @@ -140,18 +140,17 @@ get_nfip_claims = function( state_abbreviation = state, county_geoid, county_name, - occupancy_type = case_when(occupancy_type %in% c(1, 11, 14) ~ "single family", - occupancy_type %in% c(2, 12) ~ "2-4 units", - occupancy_type %in% c(3, 13, 16, 15) ~ "5+ units", - occupancy_type %in% c(14) ~ "mobile/manufactured home", - occupancy_type %in% c(4, 6, 17, 18, 19) ~ "non-residential"), + occupancy_type = dplyr::case_when(occupancy_type %in% c(1, 11, 14) ~ "single family", + occupancy_type %in% c(2, 12, 3, 13, 16, 15) ~ "multi-family", + occupancy_type %in% c(14) ~ "mobile/manufactured home", + occupancy_type %in% c(4, 6, 17, 18, 19) ~ "non-residential"), year_loss = year_of_loss, year_construction = lubridate::year(original_construction_date), count_units_insured = policy_count, ## number of insured units associated with the claim #cause_of_damage, #flood_event_name = flood_event, #flood_zone_firm_current = flood_zone_current, - deductible_building = case_when(building_deductible_code == "0" ~ 500, + deductible_building = dplyr::case_when(building_deductible_code == "0" ~ 500, building_deductible_code == "1" ~ 1000, building_deductible_code == "2" ~ 2000, building_deductible_code == "3" ~ 3000, From 48cbab7067a855e0cd9fd267b2b79f4924d97415 Mon Sep 17 00:00:00 2001 From: wcurrangroome Date: Thu, 30 Oct 2025 13:27:35 -0400 Subject: [PATCH 5/5] nfip claims finalized; API = TRUE fails, but I think this is because the API is down --- R/get_nfip_claims.R | 26 ++++++++++++-------------- man/get_nfip_claims.Rd | 14 +++++++------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/R/get_nfip_claims.R b/R/get_nfip_claims.R index 129783a..ffc1bd1 100644 --- a/R/get_nfip_claims.R +++ b/R/get_nfip_claims.R @@ -1,5 +1,3 @@ -#' @importFrom magrittr %>% - #' @title Access county-level data on NFIP claims #' @param county_geoids A character vector of five-digit county codes. NULL by default; must be non-NULL if `api = TRUE`. #' @param file_name The name (not the full path) of the Box file containing the raw data. @@ -51,14 +49,14 @@ #' @examples #' \dontrun{ #' -#' test <- get_nfip_claims(county_geoids = c("01001", "48201")) %>% -#' filter( +#' test <- get_nfip_claims(county_geoids = c("01001", "48201")) |> +#' dplyr::filter( #' year_of_loss >= 2015, ### in the past 10 years -#' !occupancy_type %in% c("non-residential")) %>% ### only residential claims -#' summarize( +#' !occupancy_type %in% c("non-residential")) |> ### only residential claims +#' dplyr::summarize( #' .by = county_geoid, -#' across(matches("payment"), sum, na.rm = TRUE), -#' residential_claims = n_distinct(nfip_claim_id)) +#' dplyr::across(dplyr::matches("payment"), sum, na.rm = TRUE), +#' residential_claims = dplyr::n_distinct(nfip_claim_id)) #'} get_nfip_claims = function( @@ -106,7 +104,7 @@ get_nfip_claims = function( df1a = purrr::map_dfr( county_geoids, ~ rfema::open_fema( - data_set = "fimanfippolicies", + data_set = "fimaNfipClaims", filters = list(countyCode = .x), ask_before_call = FALSE) |> janitor::clean_names()) @@ -137,11 +135,11 @@ get_nfip_claims = function( dplyr::transmute( #nfip_claim_id = id, state_fips, - state_abbreviation = state, + #state_abbreviation = state, ## this is unreliable--other fields appear to be more consistent county_geoid, county_name, - occupancy_type = dplyr::case_when(occupancy_type %in% c(1, 11, 14) ~ "single family", - occupancy_type %in% c(2, 12, 3, 13, 16, 15) ~ "multi-family", + occupancy_type = dplyr::case_when(occupancy_type %in% c(1, 11) ~ "single family", + occupancy_type %in% c(2, 3, 12, 13, 16, 15) ~ "multi-family", occupancy_type %in% c(14) ~ "mobile/manufactured home", occupancy_type %in% c(4, 6, 17, 18, 19) ~ "non-residential"), year_loss = year_of_loss, @@ -165,7 +163,7 @@ get_nfip_claims = function( building_deductible_code == "F" ~ 1250, building_deductible_code == "G" ~ 500, building_deductible_code == "H" ~ 200), - deductible_contents = case_when(contents_deductible_code == "0" ~ 500, + deductible_contents = dplyr::case_when(contents_deductible_code == "0" ~ 500, contents_deductible_code == "1" ~ 1000, contents_deductible_code == "2" ~ 2000, contents_deductible_code == "3" ~ 3000, @@ -190,7 +188,7 @@ get_nfip_claims = function( damage_contents = contents_damage_amount, net_payment_building = net_building_payment_amount, net_payment_contents = net_contents_payment_amount, - net_icc_payment_amount) + net_payment_icc = net_icc_payment_amount) return(result) } diff --git a/man/get_nfip_claims.Rd b/man/get_nfip_claims.Rd index 894d6ee..d480d0f 100644 --- a/man/get_nfip_claims.Rd +++ b/man/get_nfip_claims.Rd @@ -54,7 +54,7 @@ redacted to protect policy holder personally identifiable information. The dataset includes the 50 states + DC and the following territories: Puerto Rico, US Virgin Islands, and Guam. -In order to filter to residential claims, filter out occupancy types 4, 6, 17, 18, 19. +In order to filter to residential claims, filter out occupancy type: "non-residential". Some claims (from multi-unit buildings / condos) are associated with multiple insured units. When calculating the number of units covered by a claim, the analyst should use the count_units_insured column. @@ -66,13 +66,13 @@ and payments in the same time period. \examples{ \dontrun{ -test <- get_nfip_claims(county_geoids = c("01001", "48201")) \%>\% - filter( +test <- get_nfip_claims(county_geoids = c("01001", "48201")) |> + dplyr::filter( year_of_loss >= 2015, ### in the past 10 years - !occupancy_type \%in\% c(4, 6, 17, 18, 19)) \%>\% ### only residential claims - summarize( + !occupancy_type \%in\% c("non-residential")) |> ### only residential claims + dplyr::summarize( .by = county_geoid, - across(matches("payment"), sum, na.rm = TRUE), - residential_claims = n_distinct(nfip_claim_id)) + dplyr::across(dplyr::matches("payment"), sum, na.rm = TRUE), + residential_claims = dplyr::n_distinct(nfip_claim_id)) } }