diff --git a/.github/workflows/save-two-region-model-data.yaml b/.github/workflows/save-two-region-model-data.yaml index 4b8cb4b..07f1961 100644 --- a/.github/workflows/save-two-region-model-data.yaml +++ b/.github/workflows/save-two-region-model-data.yaml @@ -3,6 +3,13 @@ name: Save two-region data as .rds in parallel runs on: workflow_dispatch: # allow manual trigger + inputs: + model_spec: + description: "Model spec file (in quotes)" + required: true + default: "StateIOv1.2-shoofly" + type: string + jobs: generate-save-data: @@ -32,7 +39,7 @@ jobs: # R_REMOTES_NO_ERRORS_FROM_WARNINGS: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: r-lib/actions/setup-pandoc@v2 @@ -59,12 +66,13 @@ jobs: run: | devtools::load_all() year <- ${{ matrix.data-year }} + model_spec <- ${{ github.event.inputs.model_spec }} source("${{ matrix.script-run }}") shell: Rscript {0} # Upload .rds files - name: Upload .rds files and prepare zip for manual download - uses: actions/upload-artifact@v2.3.0 + uses: actions/upload-artifact@v4 with: # Artifact name name: data and metadata @@ -75,7 +83,7 @@ jobs: # Upload .json files - name: Upload .json files and prepare zip for manual download - uses: actions/upload-artifact@v2.3.0 + uses: actions/upload-artifact@v4 with: # Artifact name name: data and metadata diff --git a/.gitignore b/.gitignore index 4f5229e..0d7b54d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .RData .Ruserdata inst/doc/**/*.html +work diff --git a/DESCRIPTION b/DESCRIPTION index 12b1ea7..1d2d51a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: stateior Type: Package Title: US State Input-Output (stateio) R modeling software -Version: 0.2.1 +Version: 0.3.0 Date: 2022-10-20 Authors@R: c( person("Mo", "Li", email="mo.li@gdit.com", role="aut"), @@ -40,10 +40,10 @@ Imports: Depends: R (>= 3.6) Remotes: - github::USEPA/useeior@v1.1.0 + github::USEPA/useeior@two_region_disagg License: file LICENSE Encoding: UTF-8 LazyData: true -RoxygenNote: 7.2.0 +RoxygenNote: 7.3.1 Suggests: testthat (>= 2.1.0) diff --git a/R/BuildModel.R b/R/BuildModel.R index fdd802f..24351c4 100644 --- a/R/BuildModel.R +++ b/R/BuildModel.R @@ -1,6 +1,6 @@ -# Define model version +# Define model version for accessing data from DataCommons # model_ver <- utils::packageDescription(pkg = "stateior", fields = "Version") -model_ver <- NULL +model_ver <- NULL # to access the latest available data #' Build a state supply model for all 52 states/regions (including DC and Overseas) #' for a given year @@ -271,16 +271,51 @@ buildStateUseModel <- function(year) { #' to ICF if a sensitivity analysis is conducted, default is 0 due to no SA. #' @param domestic A logical value indicating whether to use Domestic Use tables, #' default is TRUE. +#' @param model optional, a model object with state tables +#' @param disagg optional, disaggregation specs #' @return A list of domestic two-region Use tables. #' @export buildTwoRegionUseModel <- function(state, year, ioschema, iolevel, ICF_sensitivity_analysis = FALSE, - adjust_by = 0, domestic = TRUE) { + adjust_by = 0, domestic = TRUE, + model = NULL, disagg = NULL) { startLogging() # 0 - Define commodities, industries, final demand columns, import column, and - # international trade adjustment column - commodities <- getVectorOfCodes(iolevel, "Commodity") - industries <- getVectorOfCodes(iolevel, "Industry") + # international trade adjustment column and + # 1 - Load state domestic Use and commodity output for the specified year + + if (is.null(model)) { + # If no model object is passed, generate these objects + commodities <- getVectorOfCodes(iolevel, "Commodity") + industries <- getVectorOfCodes(iolevel, "Industry") + SoI_DomesticUse <- loadStateIODataFile(paste0("State_", + iolevel, + "_DomesticUse_", + year), + ver = model_ver)[[state]][commodities, ] + SoI_CommodityOutput <- loadStateIODataFile(paste0("State_", + iolevel, + "_CommodityOutput_", + year), + ver = model_ver)[[state]] + US_DomesticUse <- generateUSDomesticUse(iolevel, year) + US_Make <- getNationalMake(iolevel, year) + US_Use <- getNationalUse("Summary", year) + SoI_Use <- loadStateIODataFile(paste0("State_", iolevel, "_Use_", year), + ver = model_ver)[[state]] + + } else { + commodities <- model$Commodities + industries <- model$Industries + SoI_DomesticUse <- model$DomesticFullUse[commodities, ] + SoI_CommodityOutput <- model$CommodityOutput + US_DomesticUse <- model$US_DomesticUse + US_Make <- model$US_Make + US_Use <- model$US_Use + SoI_Use <- model$FullUse + } + + FD_cols <- getFinalDemandCodes(iolevel) import_col <- getVectorOfCodes(iolevel, "Import") ITA_col <- ifelse(iolevel == "Detail", "F05100", "F051") @@ -301,25 +336,17 @@ buildTwoRegionUseModel <- function(state, year, ioschema, iolevel, # BEA column BEA_col <- paste("BEA", ioschema, iolevel, "Code", sep = "_") - # 1 - Load state domestic Use and commodity output for the specified year - logging::loginfo("Loading state Domestic Use table...") - SoI_DomesticUse <- loadStateIODataFile(paste0("State_", - iolevel, - "_DomesticUse_", - year), - ver = model_ver)[[state]][commodities, ] - # Load state commodity output - logging::loginfo("Loading state commodity output...") - SoI_CommodityOutput <- loadStateIODataFile(paste0("State_", - iolevel, - "_CommodityOutput_", - year), - ver = model_ver)[[state]] - + # Disaggregate remaining objects + if(!is.null(disagg)){ + tradable_cols <- disaggregateStateSectorLists(tradable_cols, disagg) + } + # 2 - Generate 2-region ICFs logging::loginfo("Generating two-region interregional commodity flow (ICF) ratios...") ICF <- generateDomestic2RegionICFs(state, year, ioschema, iolevel, - ICF_sensitivity_analysis, adjust_by) + ICF_sensitivity_analysis, adjust_by, disagg) + ICF <- ICF[match(rownames(SoI_CommodityOutput), ICF$BEA_2012_Summary_Code),] + # Only allocate "error" to rows (commodities) that does not have ICF of 1 or 0 commodities_notrade <- ICF[ICF$SoI2SoI == 1 & ICF$SoI2RoUS == 0 & ICF$RoUS2RoUS == 1 & ICF$RoUS2SoI == 0, 1] @@ -338,6 +365,7 @@ buildTwoRegionUseModel <- function(state, year, ioschema, iolevel, logging::loginfo("Generating SoI2SoI Use table...") SoI2SoI_Use <- SoI_DomesticUse SoI2SoI_Use[, tradable_cols] <- SoI_DomesticUse[, tradable_cols] * ICF$SoI2SoI + # Calculate Interregional Imports, Exports, and Net Exports logging::loginfo("Calculating SoI2SoI interregional imports and exports and net exports...") SoI2SoI_Use$InterregionalImports <- rowSums(SoI_DomesticUse[, tradable_cols]) - rowSums(SoI2SoI_Use[, tradable_cols]) @@ -346,11 +374,9 @@ buildTwoRegionUseModel <- function(state, year, ioschema, iolevel, # 4 - Generate RoUS domestic Use and commodity output # Generate RoUS domestic Use logging::loginfo("Generating RoUS Domestic Use table...") - US_DomesticUse <- generateUSDomesticUse(iolevel, year) RoUS_DomesticUse <- US_DomesticUse - SoI_DomesticUse # Calculate RoUS Commodity Output logging::loginfo("Generating RoUS commodity output...") - US_Make <- getNationalMake(iolevel, year) US_CommodityOutput <- colSums(US_Make) RoUS_CommodityOutput <- US_CommodityOutput - SoI_CommodityOutput colnames(RoUS_CommodityOutput) <- "Output" @@ -500,9 +526,6 @@ buildTwoRegionUseModel <- function(state, year, ioschema, iolevel, # to form two-region total Use table. if (!domestic) { # Load US and SoI Use, calcuate RoUS_Use - US_Use <- getNationalUse("Summary", year) - SoI_Use <- loadStateIODataFile(paste0("State_", iolevel, "_Use_", year), - ver = model_ver)[[state]] RoUS_Use <- US_Use - SoI_Use[commodities, c(industries, FD_cols)] # Calculate SoI_Import and RoUS_Import SoI_Import <- SoI_Use[commodities, c(industries, FD_cols)] - SoI_DomesticUse[commodities, c(industries, FD_cols)] @@ -527,7 +550,9 @@ buildTwoRegionUseModel <- function(state, year, ioschema, iolevel, } else { q_SoI_use <- rowSums(SoI2SoI_Use[, c(industries, FD_cols, "ExportResidual")]) + rowSums(SoI2RoUS_Use[, c(industries, FD_cols)]) } - if (max(abs((q_SoI - q_SoI_use)/q_SoI_use)) > 1E-2) { + q_SoI_check <- abs((q_SoI - q_SoI_use)/q_SoI_use) + q_SoI_check[is.na(q_SoI_check)] <- 0 # Convert all N/As to 0 + if (max(q_SoI_check) > 1E-2) { if (domestic) { stop(paste0(state, "'s commodity output summed from two-region Domestic Use table ", "doesn't equal to ", state, "'s commodity output.")) @@ -543,7 +568,9 @@ buildTwoRegionUseModel <- function(state, year, ioschema, iolevel, } else { q_RoUS_use <- rowSums(RoUS2RoUS_Use[, c(industries, FD_cols, "ExportResidual")]) + rowSums(RoUS2SoI_Use[, c(industries, FD_cols)]) } - if (max(abs((q_RoUS - q_RoUS_use)/q_RoUS_use)) > 1E-2) { + q_RoUS_check <- abs((q_RoUS - q_RoUS_use)/q_RoUS_use) + q_RoUS_check[is.na(q_RoUS_check)] <- 0 # Convert all N/As to 0 + if (max(q_RoUS_check) > 1E-2) { if (domestic) { stop(paste0("RoUS (of ", state, ")'s commodity output summed from two-region Domestic Use table ", "doesn't equal to RoUS's commodity output.")) @@ -569,10 +596,11 @@ buildTwoRegionUseModel <- function(state, year, ioschema, iolevel, #' @param year A numeric value between 2007 and 2017 specifying the year of interest. #' @param iolevel BEA sector level of detail, currently can only be "Summary", #' theoretically can be "Detail", or "Sector" in future versions. +#' @param disagg_specs name of disaggregation. #' @return A list of two-region make, use, domestic use, and Use tables #' as well as commodity and industry outputs by state. #' @export -assembleTwoRegionIO <- function(year, iolevel) { +assembleTwoRegionIO <- function(year, iolevel, disagg_specs=NULL) { startLogging() # Define industries, commodities, value added rows, final demand columns, and # international trade adjustment column @@ -583,10 +611,15 @@ assembleTwoRegionIO <- function(year, iolevel) { ITA_col <- ifelse(iolevel == "Detail", "F05100", "F051") # Load US Make table US_Make <- getNationalMake(iolevel, year) + US_Use <- getNationalUse(iolevel, year) US_DomesticUse <- generateUSDomesticUse(iolevel, year) # Load state Make, industry and commodity output State_Make_ls <- loadStateIODataFile(paste0("State_", iolevel, "_Make_", year)) State_Use_ls <- loadStateIODataFile(paste0("State_", iolevel, "_Use_", year)) + State_DomesticUse_ls <- loadStateIODataFile(paste0("State_", + iolevel, + "_DomesticUse_", + year)) State_IndustryOutput_ls <- loadStateIODataFile(paste0("State_", iolevel, "_IndustryOutput_", @@ -597,18 +630,102 @@ assembleTwoRegionIO <- function(year, iolevel) { "_CommodityOutput_", year), ver = model_ver) - # Assemble two-region IO tables + disagg <- NULL # Initialization + if(!is.null(disagg_specs)){ + + # Initialize model + model <- getStateModelDisaggSpecs(disagg_specs) + + + if(length(model$DisaggregationSpecs)!=0){ + disagg <- model$DisaggregationSpecs[[1]] + model$specs$CommodityorIndustryType <- "Commodity" # Needed for disaggregation of model$FinalDemand model object in useeior + + # Disaggregate national model objects + # Assign model objects + model$Industries <- industries + model$Commodities <- commodities + model$MakeTransactions <- US_Make + model$FullUse <- US_Use + model$DomesticFullUse <- US_DomesticUse # Note that the domestic full use object does not include value added rows + + # Disaggregate national model objects once (i.e. not for each state) + if(!is.null(disagg$stateDF)){ + + #model <- createDisaggFilesFromProxyData(model, disagg, year, "US") #Function to disagg by proxy + model <- useeior:::createDisaggFilesFromProxyData(model, disagg, year, "US") #Function to disagg by proxy + disagg <- model$DisaggregationSpecs[[disagg$OriginalSectorCode]] #update disagg + } + + model <- disaggregateNationalObjectsInStateModel(model, disagg) + ## ^^ this should always use national level disaggregation data + + # Assign the disaggregated model objects to the original stateior objects, rename some as national + US_Make <- model$MakeTransactions + model$US_Make <- model$MakeTransactions + US_DomesticUse <- model$DomesticFullUse + model$US_DomesticUse <- model$DomesticFullUse + model$US_Use <- model$FullUse + industries <- model$Industries + commodities <- model$Commodities + + # Loop for objects that need to be disaggregated objects for each state + for (state in sort(c(state.name, "District of Columbia", "Overseas"))) { + model$MakeTransactions <- State_Make_ls[[state]] + model$FullUse <- State_Use_ls[[state]] + model$DomesticFullUse <- State_DomesticUse_ls[[state]] + model$CommodityOutput <- State_CommodityOutput_ls[[state]] + model$IndustryOutput <- State_IndustryOutput_ls[[state]] + + if(!is.null(disagg$stateDF)) { + # Get the correct disaggregation percentages for each state + #model <- createDisaggFilesFromProxyData(model, disagg, year, state) + model <- useeior:::createDisaggFilesFromProxyData(model, disagg, year, state) + disagg <- model$DisaggregationSpecs[[disagg$OriginalSectorCode]] + } + model <- disaggregateStateModel(model, state) + + # Assign the disaggregated model objects to the stateior lists + State_Make_ls[[state]] <- model$MakeTransactions + State_Use_ls[[state]] <- model$FullUse + State_DomesticUse_ls[[state]] <- model$DomesticFullUse + State_CommodityOutput_ls[[state]] <- model$CommodityOutput + State_IndustryOutput_ls[[state]] <- model$IndustryOutput + + } #end of for each state loop + + } else { + stop("Error accessing disaggregation specs") + } + + } else { + # Initiate model object + model <- list() + model$Commodities <- commodities + model$Industries <- industries + model$US_DomesticUse <- US_DomesticUse + model$US_Make <- US_Make + model$US_Use <- US_Use + } + + # Assemble two-region IO tables TwoRegionIO <- list() for (state in sort(c(state.name, "District of Columbia"))) { + ## Two-region Make - SoI_Make <- State_Make_ls[[state]] - rownames(SoI_Make) <- getBEASectorCodeLocation("Industry", state, iolevel) - colnames(SoI_Make) <- getBEASectorCodeLocation("Commodity", state, iolevel) - RoUS_Make <- US_Make - SoI_Make - rownames(RoUS_Make) <- getBEASectorCodeLocation("Industry", "RoUS", iolevel) - colnames(RoUS_Make) <- getBEASectorCodeLocation("Commodity", "RoUS", iolevel) + model$MakeTransactions <- State_Make_ls[[state]] + model$FullUse <- State_Use_ls[[state]] + model$DomesticFullUse <- State_DomesticUse_ls[[state]] + model$CommodityOutput <- State_CommodityOutput_ls[[state]] + model$IndustryOutput <- State_IndustryOutput_ls[[state]] + + rownames(model$MakeTransactions) <- getBEASectorCodeLocation("Industry", state, iolevel, disagg) + colnames(model$MakeTransactions) <- getBEASectorCodeLocation("Commodity", state, iolevel, disagg) + RoUS_Make <- US_Make - model$MakeTransactions + rownames(RoUS_Make) <- getBEASectorCodeLocation("Industry", "RoUS", iolevel, disagg) + colnames(RoUS_Make) <- getBEASectorCodeLocation("Commodity", "RoUS", iolevel, disagg) # Form two-region Make - TwoRegionMake <- SoI_Make + TwoRegionMake <- model$MakeTransactions TwoRegionMake[rownames(RoUS_Make), colnames(RoUS_Make)] <- RoUS_Make # Replace NA with 0 in two-region Make TwoRegionMake[is.na(TwoRegionMake)] <- 0 @@ -616,23 +733,25 @@ assembleTwoRegionIO <- function(year, iolevel) { ## Two-region Use and Domestic Use table TwoRegionUseModel <- buildTwoRegionUseModel(state, year, ioschema = 2012, - iolevel = iolevel, domestic = FALSE) + iolevel = iolevel, domestic = FALSE, + model = model, disagg = disagg) TwoRegionUse <- cbind(rbind(TwoRegionUseModel[["SoI2SoI"]][commodities, c(industries, FD_cols)], TwoRegionUseModel[["RoUS2SoI"]][commodities, c(industries, FD_cols)]), rbind(TwoRegionUseModel[["SoI2RoUS"]][commodities, c(industries, FD_cols)], TwoRegionUseModel[["RoUS2RoUS"]][commodities, c(industries, FD_cols)])) TwoRegionDomesticUseModel <- buildTwoRegionUseModel(state, year, ioschema = 2012, - iolevel = iolevel, domestic = TRUE) + iolevel = iolevel, domestic = TRUE, + model = model, disagg = disagg) TwoRegionDomesticUse <- cbind(rbind(TwoRegionDomesticUseModel[["SoI2SoI"]][commodities, c(industries, FD_cols)], TwoRegionDomesticUseModel[["RoUS2SoI"]][commodities, c(industries, FD_cols)]), rbind(TwoRegionDomesticUseModel[["SoI2RoUS"]][commodities, c(industries, FD_cols)], TwoRegionDomesticUseModel[["RoUS2RoUS"]][commodities, c(industries, FD_cols)])) - rownames(TwoRegionUse) <- c(getBEASectorCodeLocation("Commodity", state, iolevel), - getBEASectorCodeLocation("Commodity", "RoUS", iolevel)) + rownames(TwoRegionUse) <- c(getBEASectorCodeLocation("Commodity", state, iolevel, disagg), + getBEASectorCodeLocation("Commodity", "RoUS", iolevel, disagg)) rownames(TwoRegionDomesticUse) <- rownames(TwoRegionUse) - colnames(TwoRegionUse) <- c(getBEASectorCodeLocation("Industry", state, iolevel), + colnames(TwoRegionUse) <- c(getBEASectorCodeLocation("Industry", state, iolevel, disagg), getBEASectorCodeLocation("FinalDemand", state, iolevel), - getBEASectorCodeLocation("Industry", "RoUS", iolevel), + getBEASectorCodeLocation("Industry", "RoUS", iolevel, disagg), getBEASectorCodeLocation("FinalDemand", "RoUS", iolevel)) colnames(TwoRegionDomesticUse) <- colnames(TwoRegionUse) TwoRegionIO[["Use"]][[state]] <- TwoRegionUse @@ -641,7 +760,7 @@ assembleTwoRegionIO <- function(year, iolevel) { ## Two-region Value Added SoI_VA <- State_Use_ls[[state]][VA_rows, industries] rownames(SoI_VA) <- getBEASectorCodeLocation("ValueAdded", state, iolevel) - colnames(SoI_VA) <- getBEASectorCodeLocation("Industry", state, iolevel) + colnames(SoI_VA) <- getBEASectorCodeLocation("Industry", state, iolevel, disagg) RoUS_VA <- (Reduce("+", State_Use_ls) - State_Use_ls[[state]])[VA_rows, industries] rownames(RoUS_VA) <- apply(cbind(VA_rows, "RoUS"), 1, joinStringswithSlashes) colnames(RoUS_VA) <- apply(cbind(industries, "RoUS"), 1, joinStringswithSlashes) @@ -661,24 +780,28 @@ assembleTwoRegionIO <- function(year, iolevel) { RoUS_CommodityOutput <- rowSums(TwoRegionDomesticUseModel[["RoUS2RoUS"]][, c(industries, FD_cols, ITA_col, "ExportResidual")]) + rowSums(TwoRegionDomesticUseModel[["RoUS2SoI"]][, c(industries, FD_cols, ITA_col)]) TwoRegionCommodityOutput <- c(SoI_CommodityOutput, RoUS_CommodityOutput) - names(TwoRegionCommodityOutput) <- c(getBEASectorCodeLocation("Commodity", state, iolevel), - getBEASectorCodeLocation("Commodity", "RoUS", iolevel)) + names(TwoRegionCommodityOutput) <- c(getBEASectorCodeLocation("Commodity", state, iolevel, disagg), + getBEASectorCodeLocation("Commodity", "RoUS", iolevel, disagg)) TwoRegionIO[["CommodityOutput"]][[state]] <- TwoRegionCommodityOutput ## Two-region Industry Output TwoRegionIndustryOutput <- c(State_IndustryOutput_ls[[state]][, "Output"], rowSums(US_Make) - State_IndustryOutput_ls[[state]][, "Output"]) - names(TwoRegionIndustryOutput) <- c(getBEASectorCodeLocation("Industry", state, iolevel), - getBEASectorCodeLocation("Industry", "RoUS", iolevel)) + names(TwoRegionIndustryOutput) <- c(getBEASectorCodeLocation("Industry", state, iolevel, disagg), + getBEASectorCodeLocation("Industry", "RoUS", iolevel, disagg)) TwoRegionIO[["IndustryOutput"]][[state]] <- TwoRegionIndustryOutput ## Two-region International Trade Adjustment SoI_ITA <- State_Use_ls[[state]][commodities, ITA_col] - names(SoI_ITA) <- getBEASectorCodeLocation("Commodity", state, iolevel) + names(SoI_ITA) <- getBEASectorCodeLocation("Commodity", state, iolevel, disagg) RoUS_ITA <- Reduce("+", State_Use_ls)[commodities, ITA_col] - SoI_ITA - names(RoUS_ITA) <- getBEASectorCodeLocation("Commodity", "RoUS", iolevel) + names(RoUS_ITA) <- getBEASectorCodeLocation("Commodity", "RoUS", iolevel, disagg) TwoRegionIO[["InternationalTradeAdjustment"]][[state]] <- c(SoI_ITA, RoUS_ITA) + # if(!is.null(disagg_specs)){ + # model <- useeior:::balanceDisagg(model, disagg) + # } + print(state) } return(TwoRegionIO) diff --git a/R/InteregionalCommodityFlowFunctions.R b/R/InteregionalCommodityFlowFunctions.R index 22572da..7129155 100644 --- a/R/InteregionalCommodityFlowFunctions.R +++ b/R/InteregionalCommodityFlowFunctions.R @@ -96,10 +96,11 @@ calculateLocalandTradedRatios <- function(state, year, SoI = TRUE, ioschema, iol #' sensitivity analysis on ICF, default is FALSE. #' @param adjust_by A numeric value between 0 and 1 indicating the manual adjustment #' to ICF if a sensitivity analysis is conducted, default is 0 due to no SA. +#' @param disagg optional, disaggregation specs #' #' @return A data frame contains domestic 2 region ICFs. generateDomestic2RegionICFs <- function(state, year, ioschema, iolevel, ICF_sensitivity_analysis = FALSE, - adjust_by = 0) { + adjust_by = 0, disagg = NULL) { # Specify BEA code bea <- paste("BEA", ioschema, iolevel, "Code", sep = "_") # Generate SoI-RoUS commodity flow ratios from FAF @@ -142,14 +143,49 @@ generateDomestic2RegionICFs <- function(state, year, ioschema, iolevel, # Merge ICF_2r_wide with complete BEA Commodity list CommodityCodeName <- loadDatafromUSEEIOR(paste(iolevel, "CommodityCodeName_2012", - sep = "_")) + sep = "_"), + appendSchema = FALSE) + # Update commodities from disaggregation + if (!is.null(disagg)){ + # disagg_df <- data.frame(BEA_2012_Summary_Commodity_Code = c("221100", "221200", "221300"), + # BEA_2012_Summary_Commodity_Name = c("Elec", "NG", "Water")) + # CommodityCodeName <- CommodityCodeName[CommodityCodeName$BEA_2012_Summary_Commodity_Code!="22",] + # CommodityCodeName <- rbind(CommodityCodeName, disagg_df) + + disagg_df <- disagg$NAICSSectorCW[,c("USEEIO_Code", "USEEIO_Name")] # Get new sector codes and names + disagg_df <- unique(disagg_df) # Keep a unique list + colnames(disagg_df) <- c(paste0("BEA_",year,"_Summary_Commodity_Code"), + paste0("BEA_",year,"_Summary_Commodity_Name")) # Make col headers match CommodityCodeName headers + # Remove last 3 characters from the code, i.e., remove /US + disagg_df$BEA_2012_Summary_Commodity_Code <- substr(disagg_df$BEA_2012_Summary_Commodity_Code, + 1,nchar(disagg_df$BEA_2012_Summary_Commodity_Code)-3) + # Remove original aggregate code, e.g., 22 for utilities + CommodityCodeName <- CommodityCodeName[CommodityCodeName$BEA_2012_Summary_Commodity_Code!= + substr(disagg$OriginalSectorCode,1,nchar(disagg$OriginalSectorCode)-3) ,] + # Add disagg codes to CommodityCodeName + CommodityCodeName <- rbind(CommodityCodeName, disagg_df) + + } + ICF <- merge(ICF_2r_wide, CommodityCodeName, by.x = bea, by.y = paste("BEA", ioschema, iolevel, "Commodity_Code", sep = "_"), all.y = TRUE) if (iolevel == "Summary") { # Adjust utilities - ICF[ICF[, bea] == "22", cols] <- calculateUtilitiesFlowRatios(state, year)[, cols] - ICF[ICF[, bea] == "22", "source"] <- "EIA" + if (is.null(disagg) || disagg$OriginalSectorCode != "22/US"){ + # If there are no disagg sectors, or if the disagg sectors is not the utilities sector, calculate flow ratios for summary sector 22 + ICF[ICF[, bea] == "22", cols] <- calculateUtilitiesFlowRatios(state, year)[, cols] + ICF[ICF[, bea] == "22", "source"] <- "EIA" + } else { + ICF[ICF[, bea] == "221100", cols] <- calculateElectricityFlowRatios(state, year)[, cols] + ICF[ICF[, bea] == "221100", "source"] <- "EIA" + ICF[ICF[, bea] %in% c("221200", "221300"), cols] <- data.frame("SoI2SoI" = 1, + "SoI2RoUS" = 0, + "RoUS2SoI" = 0, + "RoUS2RoUS" = 1) + ICF[ICF[, bea]%in% c("221200", "221300"), "source"] <- "Assuming no interregional trade" + } + # Adjust waste management and remediation services ICF[ICF[, bea] == "562", cols] <- calculateWasteManagementServiceFlowRatios(state, year)[, cols] ICF[ICF[, bea] == "562", "source"] <- "RCRAInfo and SMP" diff --git a/R/StateDisaggFunctions.R b/R/StateDisaggFunctions.R new file mode 100644 index 0000000..5b80473 --- /dev/null +++ b/R/StateDisaggFunctions.R @@ -0,0 +1,379 @@ +#' Read and assign disaggregation specifications +#' Function assumes all states will be disaggregated with the same config file +#' and allocations unless a statefile parameter is included as input. +#' In this case, the function assumes the statefile paramter will modify the +#' allocation values present in configfile for each state, rather than loading +#' in 50 different sets of allocation values. +#' @param configfile str, name of disaggregation specification file +#' @param statefile str, name of state-specific disaggregation spec file that will +#' modify the standard configfile for each state. Should be 1 config file that has +#' the required modifications of configfile for each state +#' @return A stateior model object with the disaggregation specs loaded. +getStateModelDisaggSpecs <- function(configfile, statefile = NULL){ + model <- list() + model$specs$DisaggregationSpecs <- configfile + model$specs$IODataSource <- "" + disaggConfigpath <- system.file(paste0("extdata/disaggspecs/"), paste0(configfile,".yml"), package = "stateior") + model <- useeior:::getDisaggregationSpecs(model, disaggConfigpath, pkg = "stateior") + + for(disagg in model$DisaggregationSpecs) + { + if(!is.null(disagg$stateFile)){ + disagg$stateDF <- getStateSpecificDisaggSpecs(disaggConfigpath, disagg$stateFile) + model$DisaggregationSpecs[[disagg$OriginalSectorCode]] <- disagg + } + } + return(model) +} + +#' Read in state-specific disaggregation values +#' This function assumes values contained in statefile will modify disaggregation +#' values present in the main disaggregation config file. +#' @param statefile str, name of state-specific disaggregation spec file that will +#' modify the standard configfile for each state. Should be 1 config file that has +#' the required modifications of configfile for each state +#' @param disaggConfigpath str, path for statefile +#' @return A stateior model object with the state-specific disaggregation specs +#' included in model$specs$STateDisaggSpecs object +getStateSpecificDisaggSpecs <- function(disaggConfigpath, statefile){ + filename <- file.path(dirname(disaggConfigpath), statefile) + stateFileDF <- utils::read.table(filename, sep = ",", header = TRUE, stringsAsFactors = FALSE, check.names = FALSE) + return(stateFileDF) +} + +#' Disaggregate state make and use tables +#' @param model An stateior model object with model specs and specific IO tables loaded +#' @param state A string value that indicates the state model being disaggregated +#' @return A stateior model with the disaggregateed objects +disaggregateStateModel <- function(model, state){ + + # TODO: Include validation checks for row/column sums - note that there may be unexpected + # results due to existing negative values in state use tables. + + for (disagg in model$DisaggregationSpecs){ + + logging::loginfo(paste0("Disaggregating ", disagg$OriginalSectorName," for ", state)) + + # Formatting model objects according to useeior disaggregation formats + model$MakeTransactions <- formatMakeFromStateToUSEEIO(model, state) #Formatting MakeTransactions object + model$FullUse <- formatFullUseFromStateToUSEEIO(model$FullUse) # Formatting row/column names in FullUse object + model$DomesticFullUse <- formatFullUseFromStateToUSEEIO(model$DomesticFullUse) + model <- splitFullUse(model) # Splitting FullUse into UseTransactions, UseValueAdded, and FinalDemand objects + model <- splitFullUse(model, domestic = TRUE) + + # Disaggregating specified model objects + model$MakeTransactions <- useeior:::disaggregateMakeTable(model, disagg) + model$MakeTransactions[is.na(model$MakeTransactions)] <- 0 + + model$UseTransactions <- useeior:::disaggregateUseTable(model, disagg) + model$UseTransactions[is.na(model$UseTransactions)] <- 0 + model$FinalDemand <- useeior:::disaggregateFinalDemand(model, disagg, domestic = FALSE) + model$FinalDemand[is.na(model$FinalDemand)] <- 0 + model$DomesticUseTransactions <- useeior:::disaggregateUseTable(model, disagg, domestic = TRUE) + model$DomesticUseTransactions[is.na(model$DomesticUseTransactions)] <- 0 + model$DomesticFinalDemand <- useeior:::disaggregateFinalDemand(model, disagg, domestic = TRUE) + model$DomesticFinalDemand[is.na(model$DomesticFinalDemand)] <- 0 + model$UseValueAdded <- useeior:::disaggregateVA(model, disagg) + model$UseValueAdded[is.na(model$UseValueAdded)] <- 0 + + if(model$specs$CommodityorIndustryType=="Commodity") { + model <- calculateStateIndustryCommodityOuput(model) # Also formats the disaggregated industry and commodity outputs to stateior formats + + } + # Formatting disaggregated model objects back to stateior formats + model$MakeTransactions <- formatMakeFromUSEEIOtoState(model, state) + model$FullUse <- formatFullUseFromUSEEIOtoState(model, state) + model$DomesticFullUse <- formatFullUseFromUSEEIOtoState(model, state, domestic = TRUE) + } + return(model) +} + + +#' Disaggregate national make and use tables +#' @param model An stateior model object with model specs and specific IO tables loaded +#' @param disagg Specifications for model disaggregation +#' @return A stateior model with the disaggregateed objects +disaggregateNationalObjectsInStateModel <- function(model, disagg){ + + # Format specified national stateior objects to model to prepare for disaggregation + model$origCommodities <- ncol(model$MakeTransactions) + model$origIndustries <- nrow(model$MakeTransactions) + # Format Make + model$MakeTransactions <- formatMakeFromStateToUSEEIO(model, state) #Formatting MakeTransactions object + + # Format individual domestic use objects (DomesticUseTransactions, DomesticFinalDemand) + # Note that the domestic full use object does not include value added rows + model$DomesticFullUse <- formatFullUseFromStateToUSEEIO(model$DomesticFullUse) + # Splitting FullUse into UseTransactions, UseValueAdded, and FinalDemand objects + model <- splitFullUse(model, domestic = TRUE) + model$FullUse <- formatFullUseFromStateToUSEEIO(model$FullUse) + model <- splitFullUse(model, domestic = FALSE) + + # Disaggregate model objects + # model$MakeTransactions <- useeior:::disaggregateMakeTable(model, disagg) + # model$MakeTransactions[is.na(model$MakeTransactions)] <- 0 + + model$DomesticUseTransactions <- useeior:::disaggregateUseTable(model, disagg, domestic = TRUE) + model$DomesticUseTransactions[is.na(model$DomesticUseTransactions)] <- 0 + model$DomesticFinalDemand <- useeior:::disaggregateFinalDemand(model, disagg, domestic = TRUE) + model$DomesticFinalDemand[is.na(model$DomesticFinalDemand)] <- 0 + model$UseTransactions <- useeior:::disaggregateUseTable(model, disagg) + model$UseTransactions[is.na(model$UseTransactions)] <- 0 + model$FinalDemand <- useeior:::disaggregateFinalDemand(model, disagg, domestic = FALSE) + model$FinalDemand[is.na(model$FinalDemand)] <- 0 + model$UseValueAdded <- useeior:::disaggregateVA(model, disagg) + model$UseValueAdded[is.na(model$UseValueAdded)] <- 0 + + model$MakeTransactions <- useeior:::disaggregateMakeTable(model, disagg) + model$MakeTransactions[is.na(model$MakeTransactions)] <- 0 + + model$Industries <- disaggregateStateSectorLists(model$Industries, disagg) + model$Commodities <- disaggregateStateSectorLists(model$Commodities, disagg) + + # Convert disaggregated objects back to stateior formats. Note that commodities and industries did not change format in disaggregation. + model$MakeTransactions <- formatMakeFromUSEEIOtoState(model, state = "National") + model$DomesticFullUse <- formatFullUseFromUSEEIOtoState(model, state, domestic = TRUE) + model$FullUse <- formatFullUseFromUSEEIOtoState(model, state) + + return(model) + +} + +#' Format model objects to prepare for use in useeior functions +#' @param model An stateior model object with model specs and specific IO tables loaded +#' @param state A string value that indicates the state model being disaggregated +#' @return A stateior make table formatted for disaggregation with useeior functions +formatMakeFromStateToUSEEIO <- function(model, state){ + # Formatting Make row and column names according to useeior disaggregation formats + # For make rows + rowLabels <- rownames(model$MakeTransactions) + rowLabels <- gsub(".*\\.", "", rowLabels) + rowLabels <- paste0(rowLabels, "/US") + + # For make cols + colLabels <- colnames(model$MakeTransactions) + colLabels <- paste0(colLabels, "/US") + + # Replace names with new labels + rownames(model$MakeTransactions) <- rowLabels + colnames(model$MakeTransactions) <- colLabels + + return(model$MakeTransactions) +} + +#' Format Use table objects to prepare for use in useeior functions +#' @param table FullUse table +#' @return The FullUse model object with useeior formatting fit for disaggregation functions +formatFullUseFromStateToUSEEIO <- function(table){ + + rowLabels <- rownames(table) + rowLabels <- paste0(rowLabels, "/US") + rownames(table) <- rowLabels + + columnLabels <- colnames(table) + columnLabels <- paste0(columnLabels, "/US") + colnames(table) <- columnLabels + + return(table) +} + +#' Format Make table objects back to stateior format +#' @param model An stateior model object with model specs and specific IO tables loaded +#' @param state A string value that indicates the state model being disaggregated +#' @return A stateior make table formatted according to stateior specifications +formatMakeFromUSEEIOtoState <- function(model, state){ + + rowLabels <- rownames(model$MakeTransactions) + rowLabels <- gsub("\\/.*","",rowLabels) # remove everything after "/" + if(state != "National"){ + rowLabels <- paste0(state,".",rowLabels) # add state and . before sector name to match original format for state models only + } + + rownames(model$MakeTransactions) <- rowLabels # Replace old row labels with new ones + + columnLabels <- colnames(model$MakeTransactions) + columnLabels <- gsub("\\/.*","",columnLabels) # remove everything after "/" + colnames(model$MakeTransactions) <- columnLabels # replace old column labels with new ones + + return(model$MakeTransactions) +} + +#' Format Use table objects back to stateior format +#' @param model An stateior model object with model specs and specific IO tables loaded +#' @param state A string value that indicates the state model being disaggregated +#' @param domestic A boolean that indicates whether the table to format is the domesticUse table or not +#' @return A stateior FullUse table formatted according to stateior specifications +formatFullUseFromUSEEIOtoState <- function(model, state, domestic = FALSE){ + + if(domestic == TRUE){ + model$DomesticFullUse <- cbind(model$DomesticUseTransactions, model$DomesticFinalDemand) # combine UseTransactions and FinalDemand columns + + # Format row and column names + rownames(model$DomesticFullUse) <- gsub("\\/.*","",rownames(model$DomesticFullUse)) # remove everything after "/" + colnames(model$DomesticFullUse) <- gsub("\\/.*","",colnames(model$DomesticFullUse)) # remove everything after "/" + return(model$DomesticFullUse) + + } else { + tempFullUse <- cbind(model$UseTransactions, model$FinalDemand) # combine UseTransactions and FinalDemand columns + + # Create the empty section of FullUse that is VA rows by FD columns (NA values) + VAbyFDSection <- data.frame(matrix(nrow = dim(model$UseValueAdded)[1], + ncol = ncol(tempFullUse) - ncol(model$UseTransactions))) + + # Rename rows and cols of new dataframe to allow cbind operation + colnames(VAbyFDSection) <- colnames(model$FinalDemand) + rownames(VAbyFDSection) <- rownames(model$UseValueAdded) + + tempVA <- cbind(model$UseValueAdded, VAbyFDSection) # combine UseValueAdded and VAbyFDSection columns + + # Assemble FullUse table and rename according to stateior formats + model$FullUse <- rbind(tempFullUse, tempVA) + rownames(model$FullUse) <- gsub("\\/.*","",rownames(model$FullUse)) # remove everything after "/" + colnames(model$FullUse) <- gsub("\\/.*","",colnames(model$FullUse)) # remove everything after "/" + return(model$FullUse) + } + +} + +#' Separate full use table into model components +#' @param model An stateior model object with model specs and specific IO tables loaded +#' @param domestic A boolean that indicates whether the table to format is the domesticUse table or not +#' @return A model object with FullUse split into UseTransactions, FinalDemand, and UseValueAdded objects +splitFullUse <- function(model, domestic = FALSE){ + + numCommodities <- model$origCommodities # Find number of commodities + numIndustries <- model$origIndustries # Find number of industries + if(domestic == TRUE){ + # Get subset of FullUse with numCommodities rows and numIndustries columns + model$DomesticUseTransactions <- model$DomesticFullUse[1:numCommodities, 1:numIndustries] + # Get subset of FullUse, with numCommodities rows and starting from columns after numIndustries + model$DomesticFinalDemand <- model$DomesticFullUse[1:numCommodities,-(1:numIndustries)] + + } else { + # Get subset of FullUse with numCommodities rows and numIndustries columns + model$UseTransactions <- model$FullUse[1:numCommodities, 1:numIndustries] + # Get subset of FullUse, starting from rows after numCommodities, with numIndustries columns + model$UseValueAdded <- model$FullUse[-(1:numCommodities),1:numIndustries] + # Get subset of FullUse, with numCommodities rows and starting from columns after numIndustries + model$FinalDemand <- model$FullUse[1:numCommodities,-(1:numIndustries)] + } + return(model) +} + +#' Calculate output from model objects +#' @param model An stateior model object with model specs and specific IO tables loaded +#' @return A model object with disaggregated IndustryOutput and CommodityOutput objects +calculateStateIndustryCommodityOuput <- function(model){ + + # Calculating and formatting IndustryOutput + model$IndustryOutput <- data.frame(colSums(model$UseTransactions) + colSums(model$UseValueAdded)) + colnames(model$IndustryOutput) <- "Output" + rowLabels <- rownames(model$IndustryOutput) + rowLabels <- gsub("\\/.*","",rowLabels) # remove everything after "/" + rownames(model$IndustryOutput) <- rowLabels + + # Calculating and formatting CommodityOuput + model$CommodityOutput <- data.frame(colSums(model$MakeTransactions)) + colnames(model$CommodityOutput) <- "Output" + rowLabels <- rownames(model$CommodityOutput) + rowLabels <- gsub("\\/.*","",rowLabels) # remove everything after "/" + rownames(model$CommodityOutput) <- rowLabels + + return(model) +} + +#' Disaggregate model$Commodity or model$Industry dataframes in the main model object +#' @param code_vector A list of sector codes (industry or commodity) +#' @param disagg Specifications for disaggregating the current Table +#' @return newList A list which contain the disaggregated model$Commodity or model$Industry objects +disaggregateStateSectorLists <- function(code_vector, disagg) { + + originalSectorCode <- gsub("\\/.*","",disagg$OriginalSectorCode) # remove everything after "/" + disaggCodes <- gsub("\\/.*","",disagg$NewSectorCodes) # remove everything after "/" + originalIndex <- grep(paste0("^",originalSectorCode,"$"), code_vector) # the ^ and $ are required to find an exact match + + newList <- append(code_vector[1:originalIndex -1], disaggCodes) + newList <- append(newList, code_vector[-(1:originalIndex)] ) # have to do this in two steps otherwise get an error + + return(newList) +} + + +#### Functions below this line are used for creating disaggFiles from Proxy data, e.g., Make and USe files from Employment ratios. + +#' Create Make, Use, and Env ratio files for each state from Proxy data for the relevant sectors. +#' @param model An stateior model object with model specs and specific IO tables loaded +#' @param disagg Specifications for disaggregating the current Table +#' @param disaggYear Integer specifying the state model year +#' @param disaggState A string value that indicates the state model being disaggregated. For national models, string should be "US" +#' @return A stateior model with disaggregation specs included +createDisaggFilesFromProxyData <- function(model, disagg, disaggYear, disaggState){ + + # Note: this function assumes: + # 1) The disaggregation will use the same proxy values for all disaggregated sectors across all rows and columns. + # That is, if we are disaggregating Summary 22 into the 3 Detail utility sectors, and the proxy allocations are (for example) 0.5/0.25/0.25, then + # in the Use table, the three Detail utility commodities (rows) will have that same split for across all columns (industries/final demand) + # 2) The disagg parameter will contain a disagg$stateDF variable that includes the data for the relevant disaggState and disaggYear parameters. + + stop("The function is not yet valid") + + temp <-1 + + #Get subset of ratios for current year + stateDFYear <- subset(disagg$stateDF, Year == disaggYear & State == disaggState) + + # If the state/year combination is not found, assume a uniform split between sectors + if(dim(stateDFYear)[1] == 0){ + + activity <- unlist(disagg$NewSectorCodes) + uniformAllocationVector <- 1/length(disagg$NewSectorCodes) + share <- rep(uniformAllocationVector,length(disagg$NewSectorCodes)) + + stateDFYear <- data.frame(State = rep(disaggState, length(disagg$NewSectorCodes)), + Activity = activity, + Share = share, + Year = rep(disaggYear, length(disagg$NewSectorCodes))) + } + + print(paste0("For ",disaggState,"-",disaggYear, " the allocation to disaggregate ", + disagg$OriginalSectorCode, " into ", disagg$NewSectorCodes, " is ", stateDFYear$Share)) + + # Default Make DF based on proxy employment values + # Specifying commodity disaggregation (column splits) for Make DF + industries <- c(rep(disagg$OriginalSectorCode,length(disagg$NewSectorCodes))) + commodities <- unlist(disagg$NewSectorCodes) + PercentMake <- stateDFYear$Share + # need to add code to ensure that the order of stateDF$Share is the same as the order of disagg$NewSectorCodes + note <- c(rep("CommodityDisagg", length(disagg$NewSectorCodes))) + + # need to rename the columns with the correct column names + makeDF <- data.frame(cbind(data.frame(industries), data.frame(commodities), data.frame(PercentMake), data.frame(note))) + colnames(makeDF) <- c("IndustryCode","CommodityCode", "PercentMake", "Note") + + + # Default Use DF based on employment ratios + # Specifying industry disaggregation (column splits) for Use DF + industries <- unlist(disagg$NewSectorCodes) + commodities <- c(rep(disagg$OriginalSectorCode,length(disagg$NewSectorCodes))) + PercentUse <- stateDFYear$Share + note <- c(rep("IndustryDisagg", length(disagg$NewSectorCodes))) + + # need to rename the columns with the correct column names + useDF <- data.frame(cbind(data.frame(industries), data.frame(commodities), data.frame(PercentUse), data.frame(note))) + useDF_2 <- makeDF # so that colnames match + colnames(useDF) <- c("IndustryCode","CommodityCode", "PercentUse", "Note") + colnames(useDF_2) <- c("IndustryCode","CommodityCode", "PercentUse", "Note") + + # need to bind makeDF because disaggregation procedure requires the UseDF to have the default commodity and industry output. + useDF <- rbind(useDF, useDF_2) + + # Add new DFs to disagg and to model + disagg$MakeFileDF <- makeDF + disagg$UseFileDF <- useDF + + model$DisaggregationSpecs[[disagg$OriginalSectorCode]] <- disagg + + temp <-2 + return(model) + +} diff --git a/R/UtilityFunctions.R b/R/UtilityFunctions.R index 21eb13a..ec66805 100644 --- a/R/UtilityFunctions.R +++ b/R/UtilityFunctions.R @@ -6,9 +6,17 @@ startLogging <- function() { #' Load data from useeior using flexible dataset name #' @param dataset A string specifying name of the data to load +#' @param appendSchema bool, set to FALSE to ignore schema in name #' @return The data loaded from useeior -loadDatafromUSEEIOR <- function(dataset) { - utils::data(package = "useeior", list = dataset) +loadDatafromUSEEIOR <- function(dataset, appendSchema = TRUE) { + if(appendSchema && !"sch" %in% dataset) { + dataset_srch <- paste0(dataset, "_12sch") + # currently only uses 2012 schema + # required due to renaming in useeior #280 + } else { + dataset_srch <- dataset + } + utils::data(package = "useeior", list = dataset_srch) df <- get(dataset) return(df) } @@ -105,14 +113,18 @@ loadBEAStateDatatoBEASummaryMapping <- function(dataname) { #' @param location A text value specifying desired location, #' can be state name like "Georgia" or "RoUS" representing Rest of US. #' @param iolevel Level of detail, can be "Sector", "Summary, "Detail". +#' @param disagg optional, disaggregation specs #' @return A text value in the format of code/location. -getBEASectorCodeLocation <- function(sector_type, location, iolevel) { +getBEASectorCodeLocation <- function(sector_type, location, iolevel, disagg=NULL) { # Get code if (sector_type != "FinalDemand") { if (sector_type == "InternationalTradeAdjustment") { code <- ifelse(iolevel == "Detail", "F05100", "F051") } else { code <- getVectorOfCodes(iolevel, sector_type) + if (!is.null(disagg)) { + code <- disaggregateStateSectorLists(code, disagg) + } } } else { code <- getFinalDemandCodes(iolevel) diff --git a/data-raw/TwoRegionModel.R b/data-raw/TwoRegionModel.R index 17137be..cd9bfde 100644 --- a/data-raw/TwoRegionModel.R +++ b/data-raw/TwoRegionModel.R @@ -1,11 +1,24 @@ # Generate and save two-region IO tables + +# model_spec <- "StateIOv1.2-milkbar" # Utilities disaggregation +# model_spec <- "StateIOv1.2-shoofly" # base model +# year <- 2019 + +# Load model spec +logging::loginfo(paste("Generating two region model for", model_spec)) +configpath <- system.file("extdata/modelspecs/", paste0(model_spec, ".yml"), package = "stateior") +specs <- configr::read.config(configpath) + # Build model -TwoRegionModel <- assembleTwoRegionIO(year, iolevel = "Summary") +TwoRegionModel <- assembleTwoRegionIO(year, iolevel = specs$BaseIOLevel, + disagg_specs = specs$DisaggregationSpecs) +alias <- gsub("^.*-", "", model_spec) + # Subset data set for (name in names(TwoRegionModel)) { df <- TwoRegionModel[[name]] # Write data to .rds - data_name <- paste("TwoRegion_Summary", name, year, + data_name <- paste("TwoRegion_Summary", name, alias, year, utils::packageDescription("stateior", fields = "Version"), sep = "_") saveRDS(object = df, diff --git a/inst/extdata/disaggspecs/UtilityDisaggregation.yml b/inst/extdata/disaggspecs/UtilityDisaggregation.yml new file mode 100644 index 0000000..40f2635 --- /dev/null +++ b/inst/extdata/disaggspecs/UtilityDisaggregation.yml @@ -0,0 +1,9 @@ +Disaggregation: + 22/US: + OriginalSectorCode: "22/US" + OriginalSectorName: "Utilities" + DisaggregationType: "Userdefined" + SectorFile: UtilityDisaggregation_Sectors.csv + MakeFile: UtilityDisaggregationSummary_Make.csv # Ratios from 2012 US Make table + UseFile: UtilityDisaggregationSummary_Use.csv # Ratios from 2012 US Use table + package: "useeior" diff --git a/inst/extdata/modelspecs/StateIOv1.2-milkbar.yml b/inst/extdata/modelspecs/StateIOv1.2-milkbar.yml new file mode 100644 index 0000000..a268451 --- /dev/null +++ b/inst/extdata/modelspecs/StateIOv1.2-milkbar.yml @@ -0,0 +1,31 @@ +Model: "StateIOv1.2-milkbar" # alias milkbar reflects summary level disaggregated model for utilities +BaseIOSchema: 2012 +BaseIOLevel: "Summary" +IOYear: + - 2012 + - 2013 + - 2014 + - 2015 + - 2016 + - 2017 + - 2018 + - 2019 + - 2020 +GeoScale: + - "State" + - "TwoRegion" # SoI and RoUS +IODataSource: "BEA" +BasePriceType: "PRO" +BasewithRedefinitions: FALSE +ScrapIncluded: FALSE +DisaggregationSpecs: "UtilityDisaggregation" + +DataProduct: + - "Make" + - "Use" + - "DomesticUse" + - "DomesticUsewithTrade" + - "InternationalTradeAdjustment" + - "CommodityOutput" + - "IndustryOutput" + - "ValueAdded" diff --git a/inst/extdata/modelspecs/StateIOv1.2-shoofly.yml b/inst/extdata/modelspecs/StateIOv1.2-shoofly.yml new file mode 100644 index 0000000..c6b715f --- /dev/null +++ b/inst/extdata/modelspecs/StateIOv1.2-shoofly.yml @@ -0,0 +1,31 @@ +Model: "StateIOv1.2-shoofly" # Summary level (73 commodities & 71 industries), no adjustments +BaseIOSchema: 2012 +BaseIOLevel: "Summary" +IOYear: + - 2012 + - 2013 + - 2014 + - 2015 + - 2016 + - 2017 + - 2018 + - 2019 + - 2020 +GeoScale: + - "State" + - "TwoRegion" # SoI and RoUS +IODataSource: "BEA" +BasePriceType: "PRO" +BasewithRedefinitions: FALSE +ScrapIncluded: FALSE +DisaggregationSpecs: NULL + +DataProduct: + - "Make" + - "Use" + - "DomesticUse" + - "DomesticUsewithTrade" + - "InternationalTradeAdjustment" + - "CommodityOutput" + - "IndustryOutput" + - "ValueAdded" diff --git a/man/assembleTwoRegionIO.Rd b/man/assembleTwoRegionIO.Rd index 947038f..37667de 100644 --- a/man/assembleTwoRegionIO.Rd +++ b/man/assembleTwoRegionIO.Rd @@ -4,13 +4,15 @@ \alias{assembleTwoRegionIO} \title{Assemble two-region make, use, domestic use, and Use tables as well as commodity and industry outputs.} \usage{ -assembleTwoRegionIO(year, iolevel) +assembleTwoRegionIO(year, iolevel, disagg_specs = NULL) } \arguments{ \item{year}{A numeric value between 2007 and 2017 specifying the year of interest.} \item{iolevel}{BEA sector level of detail, currently can only be "Summary", theoretically can be "Detail", or "Sector" in future versions.} + +\item{disagg_specs}{name of disaggregation.} } \value{ A list of two-region make, use, domestic use, and Use tables diff --git a/man/buildTwoRegionUseModel.Rd b/man/buildTwoRegionUseModel.Rd index d3ecf62..d669429 100644 --- a/man/buildTwoRegionUseModel.Rd +++ b/man/buildTwoRegionUseModel.Rd @@ -11,7 +11,9 @@ buildTwoRegionUseModel( iolevel, ICF_sensitivity_analysis = FALSE, adjust_by = 0, - domestic = TRUE + domestic = TRUE, + model = NULL, + disagg = NULL ) } \arguments{ @@ -32,6 +34,10 @@ to ICF if a sensitivity analysis is conducted, default is 0 due to no SA.} \item{domestic}{A logical value indicating whether to use Domestic Use tables, default is TRUE.} + +\item{model}{optional, a model object with state tables} + +\item{disagg}{optional, disaggregation specs} } \value{ A list of domestic two-region Use tables. diff --git a/man/calculateStateIndustryCommodityOuput.Rd b/man/calculateStateIndustryCommodityOuput.Rd new file mode 100644 index 0000000..0b5f46f --- /dev/null +++ b/man/calculateStateIndustryCommodityOuput.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/StateDisaggFunctions.R +\name{calculateStateIndustryCommodityOuput} +\alias{calculateStateIndustryCommodityOuput} +\title{Calculate output from model objects} +\usage{ +calculateStateIndustryCommodityOuput(model) +} +\arguments{ +\item{model}{An stateior model object with model specs and specific IO tables loaded} +} +\value{ +A model object with disaggregated IndustryOutput and CommodityOutput objects +} +\description{ +Calculate output from model objects +} diff --git a/man/createDisaggFilesFromProxyData.Rd b/man/createDisaggFilesFromProxyData.Rd new file mode 100644 index 0000000..4a795ae --- /dev/null +++ b/man/createDisaggFilesFromProxyData.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/StateDisaggFunctions.R +\name{createDisaggFilesFromProxyData} +\alias{createDisaggFilesFromProxyData} +\title{Create Make, Use, and Env ratio files for each state from Proxy data for the relevant sectors.} +\usage{ +createDisaggFilesFromProxyData(model, disagg, disaggYear, disaggState) +} +\arguments{ +\item{model}{An stateior model object with model specs and specific IO tables loaded} + +\item{disagg}{Specifications for disaggregating the current Table} + +\item{disaggYear}{Integer specifying the state model year} + +\item{disaggState}{A string value that indicates the state model being disaggregated. For national models, string should be "US"} +} +\value{ +A stateior model with disaggregation specs included +} +\description{ +Create Make, Use, and Env ratio files for each state from Proxy data for the relevant sectors. +} diff --git a/man/disaggregateNationalObjectsInStateModel.Rd b/man/disaggregateNationalObjectsInStateModel.Rd new file mode 100644 index 0000000..352b4f5 --- /dev/null +++ b/man/disaggregateNationalObjectsInStateModel.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/StateDisaggFunctions.R +\name{disaggregateNationalObjectsInStateModel} +\alias{disaggregateNationalObjectsInStateModel} +\title{Disaggregate national make and use tables} +\usage{ +disaggregateNationalObjectsInStateModel(model, disagg) +} +\arguments{ +\item{model}{An stateior model object with model specs and specific IO tables loaded} + +\item{disagg}{Specifications for model disaggregation} +} +\value{ +A stateior model with the disaggregateed objects +} +\description{ +Disaggregate national make and use tables +} diff --git a/man/disaggregateStateModel.Rd b/man/disaggregateStateModel.Rd new file mode 100644 index 0000000..2eed51a --- /dev/null +++ b/man/disaggregateStateModel.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/StateDisaggFunctions.R +\name{disaggregateStateModel} +\alias{disaggregateStateModel} +\title{Disaggregate state make and use tables} +\usage{ +disaggregateStateModel(model, state) +} +\arguments{ +\item{model}{An stateior model object with model specs and specific IO tables loaded} + +\item{state}{A string value that indicates the state model being disaggregated} +} +\value{ +A stateior model with the disaggregateed objects +} +\description{ +Disaggregate state make and use tables +} diff --git a/man/disaggregateStateSectorLists.Rd b/man/disaggregateStateSectorLists.Rd new file mode 100644 index 0000000..486e85f --- /dev/null +++ b/man/disaggregateStateSectorLists.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/StateDisaggFunctions.R +\name{disaggregateStateSectorLists} +\alias{disaggregateStateSectorLists} +\title{Disaggregate model$Commodity or model$Industry dataframes in the main model object} +\usage{ +disaggregateStateSectorLists(code_vector, disagg) +} +\arguments{ +\item{code_vector}{A list of sector codes (industry or commodity)} + +\item{disagg}{Specifications for disaggregating the current Table} +} +\value{ +newList A list which contain the disaggregated model$Commodity or model$Industry objects +} +\description{ +Disaggregate model$Commodity or model$Industry dataframes in the main model object +} diff --git a/man/formatFullUseFromStateToUSEEIO.Rd b/man/formatFullUseFromStateToUSEEIO.Rd new file mode 100644 index 0000000..ea83991 --- /dev/null +++ b/man/formatFullUseFromStateToUSEEIO.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/StateDisaggFunctions.R +\name{formatFullUseFromStateToUSEEIO} +\alias{formatFullUseFromStateToUSEEIO} +\title{Format Use table objects to prepare for use in useeior functions} +\usage{ +formatFullUseFromStateToUSEEIO(table) +} +\arguments{ +\item{table}{FullUse table} +} +\value{ +The FullUse model object with useeior formatting fit for disaggregation functions +} +\description{ +Format Use table objects to prepare for use in useeior functions +} diff --git a/man/formatFullUseFromUSEEIOtoState.Rd b/man/formatFullUseFromUSEEIOtoState.Rd new file mode 100644 index 0000000..2e74c33 --- /dev/null +++ b/man/formatFullUseFromUSEEIOtoState.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/StateDisaggFunctions.R +\name{formatFullUseFromUSEEIOtoState} +\alias{formatFullUseFromUSEEIOtoState} +\title{Format Use table objects back to stateior format} +\usage{ +formatFullUseFromUSEEIOtoState(model, state, domestic = FALSE) +} +\arguments{ +\item{model}{An stateior model object with model specs and specific IO tables loaded} + +\item{state}{A string value that indicates the state model being disaggregated} + +\item{domestic}{A boolean that indicates whether the table to format is the domesticUse table or not} +} +\value{ +A stateior FullUse table formatted according to stateior specifications +} +\description{ +Format Use table objects back to stateior format +} diff --git a/man/formatMakeFromStateToUSEEIO.Rd b/man/formatMakeFromStateToUSEEIO.Rd new file mode 100644 index 0000000..6de3629 --- /dev/null +++ b/man/formatMakeFromStateToUSEEIO.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/StateDisaggFunctions.R +\name{formatMakeFromStateToUSEEIO} +\alias{formatMakeFromStateToUSEEIO} +\title{Format model objects to prepare for use in useeior functions} +\usage{ +formatMakeFromStateToUSEEIO(model, state) +} +\arguments{ +\item{model}{An stateior model object with model specs and specific IO tables loaded} + +\item{state}{A string value that indicates the state model being disaggregated} +} +\value{ +A stateior make table formatted for disaggregation with useeior functions +} +\description{ +Format model objects to prepare for use in useeior functions +} diff --git a/man/formatMakeFromUSEEIOtoState.Rd b/man/formatMakeFromUSEEIOtoState.Rd new file mode 100644 index 0000000..9635f48 --- /dev/null +++ b/man/formatMakeFromUSEEIOtoState.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/StateDisaggFunctions.R +\name{formatMakeFromUSEEIOtoState} +\alias{formatMakeFromUSEEIOtoState} +\title{Format Make table objects back to stateior format} +\usage{ +formatMakeFromUSEEIOtoState(model, state) +} +\arguments{ +\item{model}{An stateior model object with model specs and specific IO tables loaded} + +\item{state}{A string value that indicates the state model being disaggregated} +} +\value{ +A stateior make table formatted according to stateior specifications +} +\description{ +Format Make table objects back to stateior format +} diff --git a/man/generateDomestic2RegionICFs.Rd b/man/generateDomestic2RegionICFs.Rd index 31d2fc1..df927c9 100644 --- a/man/generateDomestic2RegionICFs.Rd +++ b/man/generateDomestic2RegionICFs.Rd @@ -10,7 +10,8 @@ generateDomestic2RegionICFs( ioschema, iolevel, ICF_sensitivity_analysis = FALSE, - adjust_by = 0 + adjust_by = 0, + disagg = NULL ) } \arguments{ @@ -27,7 +28,9 @@ theoretically can be "Detail", or "Sector" in future versions.} sensitivity analysis on ICF, default is FALSE.} \item{adjust_by}{A numeric value between 0 and 1 indicating the manual adjustment -to ICF if a sensitivity analysis is conducted, default is 0 due to no SA. +to ICF if a sensitivity analysis is conducted, default is 0 due to no SA.} + +\item{disagg}{optional, disaggregation specs #' @return A data frame contains domestic 2 region ICFs.} } \description{ diff --git a/man/getBEASectorCodeLocation.Rd b/man/getBEASectorCodeLocation.Rd index 045405e..51f1c6b 100644 --- a/man/getBEASectorCodeLocation.Rd +++ b/man/getBEASectorCodeLocation.Rd @@ -4,7 +4,7 @@ \alias{getBEASectorCodeLocation} \title{Combine sector code and location to the form of code/location.} \usage{ -getBEASectorCodeLocation(sector_type, location, iolevel) +getBEASectorCodeLocation(sector_type, location, iolevel, disagg = NULL) } \arguments{ \item{sector_type}{A text value specifying desired sector type, @@ -14,6 +14,8 @@ can be "Commodity", "Industry", "FinalDemand", or "ValueAdded".} can be state name like "Georgia" or "RoUS" representing Rest of US.} \item{iolevel}{Level of detail, can be "Sector", "Summary, "Detail".} + +\item{disagg}{optional, disaggregation specs} } \value{ A text value in the format of code/location. diff --git a/man/getStateModelDisaggSpecs.Rd b/man/getStateModelDisaggSpecs.Rd new file mode 100644 index 0000000..23e2309 --- /dev/null +++ b/man/getStateModelDisaggSpecs.Rd @@ -0,0 +1,31 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/StateDisaggFunctions.R +\name{getStateModelDisaggSpecs} +\alias{getStateModelDisaggSpecs} +\title{Read and assign disaggregation specifications +Function assumes all states will be disaggregated with the same config file +and allocations unless a statefile parameter is included as input. +In this case, the function assumes the statefile paramter will modify the +allocation values present in configfile for each state, rather than loading +in 50 different sets of allocation values.} +\usage{ +getStateModelDisaggSpecs(configfile, statefile = NULL) +} +\arguments{ +\item{configfile}{str, name of disaggregation specification file} + +\item{statefile}{str, name of state-specific disaggregation spec file that will +modify the standard configfile for each state. Should be 1 config file that has +the required modifications of configfile for each state} +} +\value{ +A stateior model object with the disaggregation specs loaded. +} +\description{ +Read and assign disaggregation specifications +Function assumes all states will be disaggregated with the same config file +and allocations unless a statefile parameter is included as input. +In this case, the function assumes the statefile paramter will modify the +allocation values present in configfile for each state, rather than loading +in 50 different sets of allocation values. +} diff --git a/man/getStateSpecificDisaggSpecs.Rd b/man/getStateSpecificDisaggSpecs.Rd new file mode 100644 index 0000000..532f993 --- /dev/null +++ b/man/getStateSpecificDisaggSpecs.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/StateDisaggFunctions.R +\name{getStateSpecificDisaggSpecs} +\alias{getStateSpecificDisaggSpecs} +\title{Read in state-specific disaggregation values +This function assumes values contained in statefile will modify disaggregation +values present in the main disaggregation config file.} +\usage{ +getStateSpecificDisaggSpecs(disaggConfigpath, statefile) +} +\arguments{ +\item{disaggConfigpath}{str, path for statefile} + +\item{statefile}{str, name of state-specific disaggregation spec file that will +modify the standard configfile for each state. Should be 1 config file that has +the required modifications of configfile for each state} +} +\value{ +A stateior model object with the state-specific disaggregation specs +included in model$specs$STateDisaggSpecs object +} +\description{ +Read in state-specific disaggregation values +This function assumes values contained in statefile will modify disaggregation +values present in the main disaggregation config file. +} diff --git a/man/loadDatafromUSEEIOR.Rd b/man/loadDatafromUSEEIOR.Rd index 0666081..11b0296 100644 --- a/man/loadDatafromUSEEIOR.Rd +++ b/man/loadDatafromUSEEIOR.Rd @@ -4,10 +4,12 @@ \alias{loadDatafromUSEEIOR} \title{Load data from useeior using flexible dataset name} \usage{ -loadDatafromUSEEIOR(dataset) +loadDatafromUSEEIOR(dataset, appendSchema = TRUE) } \arguments{ \item{dataset}{A string specifying name of the data to load} + +\item{appendSchema}{bool, set to FALSE to ignore schema in name} } \value{ The data loaded from useeior diff --git a/man/splitFullUse.Rd b/man/splitFullUse.Rd new file mode 100644 index 0000000..11fe8c4 --- /dev/null +++ b/man/splitFullUse.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/StateDisaggFunctions.R +\name{splitFullUse} +\alias{splitFullUse} +\title{Separate full use table into model components} +\usage{ +splitFullUse(model, domestic = FALSE) +} +\arguments{ +\item{model}{An stateior model object with model specs and specific IO tables loaded} + +\item{domestic}{A boolean that indicates whether the table to format is the domesticUse table or not} +} +\value{ +A model object with FullUse split into UseTransactions, FinalDemand, and UseValueAdded objects +} +\description{ +Separate full use table into model components +}