For this example I am running the model "USEEIOv2.1.19-GHG".
I'd like to see what happens to the coefficient for Carbon dioxide from the Electric power industry.
For convenience I worked right in the pulled useeior code (master branch) and I put the model spec file for that model into the useeior/inst/extdata/modelspecs
folder.
Instead of loading the built useeior library, I use devtools to load_all() the functions and data in the package
For building the model, I just first want to run the initial steps to get what is needed for this example.
modelname <- "USEEIOv2.1.19-GHG"
model <- initializeModel(modelname)
model <- loadIOData(model)
model <- loadandbuildSatelliteTables(model)
Note that the last three lines are what's inside the wrapper buildModel function.
That results in an incomplete model object but it has the satellite table data and output data needed.
Now let's looking inside the useeior code. The buildModel.R script has the high level functions controlling this model build.
Within buildModel.R, the satellite table coefficient building happens during the beginning of constructEEIOMatrices(). A totals by sector df (TbS) is added to the model list as model$TbS which is needed because called the function to create the coefficient-by-sector df, CbS
lns 21-27 of buildModel.R
constructEEIOMatrices <- function(model) {
# Combine data into a single totals by sector df
model$TbS <- do.call(rbind,model$SatelliteTables$totals_by_sector)
# Set common year for flow when more than one year exists
model$TbS <- setCommonYearforFlow(model$TbS)
# Generate coefficients
model$CbS <- generateCbSfromTbSandModel(model)
I'm running the first two lined for my example model so that I have the TbS to work with Let's see what the total CO2 is for Electric power by subsetting the dataframe(df) and save that value as CO2_total
#Get value just for CO2 for electricity power sector
df <- subset(model$TbS, (Flowable=="Carbon dioxide" & Sector=="221100"), select=c("Flowable","FlowAmount","Unit","SectorName","Year"))
df
# Flowable FlowAmount Unit SectorName Year
#Carbon dioxide 1.332348e+12 kg Electric power generation, transmission, and distribution 2019
CO2_total <- df$FlowAmount
Processing with the modeling building code, take a look at what happens that is relevant inside generateCbSfromTbSandModel()
lns 172-177, buildModel.R
for (year in data_years){
cbs_r_y <- generateFlowtoDollarCoefficient(tbs_r[tbs_r$Year==year, ], year,
model$specs$IOYear, r, IsRoUS = IsRoUS,
model, output_type = "Industry")
cbs_r <- rbind(cbs_r,cbs_r_y)
}
For every year present in the totals-by-setor df, the records are subset and sent to this function. Note that the IOYear is sent as well. Looking at what this function takes as parameter. The year of the total-by-sector value, which is the same as the data year, is set as the output year, and the IO table year is sent as the reference year.
lns 68-70, SatelliteFunctions.R
generateFlowtoDollarCoefficient <- function (sattable, outputyear, referenceyear, location_acronym, IsRoUS = FALSE, model, output_type = "Industry") {
# Generate adjusted industry output
Output_adj <- adjustOutputbyCPI(outputyear, referenceyear, location_acronym, IsRoUS, model, output_type)
The 'adjustOutputbyCPI' receives the output year and reference year. Let's take a look at it
lns 11-15, IOFunctions.R
adjustOutputbyCPI <- function (outputyear, referenceyear, location_acronym, IsRoUS, model, output_type) {
# Load Industry Gross Output
selected_rows <- grepl(location_acronym, rownames(model$MultiYearIndustryOutput))
Output <- cbind.data.frame(rownames(model$MultiYearIndustryOutput[selected_rows, ]),
model$MultiYearIndustryOutput[selected_rows, as.character(outputyear)])
Initially this function is just getting the output of the output year for the location of interest. This returns a df of output by industry for the output year.
For my example, I will set the values I need to set so I can get this Output df.
outputyear <- 2019
> model$specs$IOYear
#[1] 2012
referenceyear <- model$specs$IOYear
location_acronym <- "US"
IsRoUS <- FALSE
output_type <- "Industry"
The I will get the output for electricity for 2019. That is in 2019 USD (current prices).
# What is 2019 output
x_elec <- subset(Output,SectorCode=="221100/US",select=Output)
x_elec <- as.numeric(x_elec)
x_elec
#[1] 4.39108e+11
With that I can calculate a coefficient of CO2_total over that output that represents 2019 CO2 emissions intensity per 2019 USD output from the electric power sector.
CO2_elec_kg_per_2019USD <- CO2_total/x_elec
CO2_elec_kg_per_2019USD
#[1] 3.034216
useeior does not calculate or store that coefficient directly. Instead it wants to adjust that 2019 output from 2019 USD to to 2012 USD and store that.
lns 18-21, IOFunctions.R
AdjustedOutput <- merge(Output, model[[paste0("MultiYear", output_type, "CPI")]][, as.character(c(referenceyear, outputyear))],
by.x = "SectorCode", by.y = 0)
AdjustedOutput$DollarRatio <- AdjustedOutput[, as.character(referenceyear)]/AdjustedOutput[, as.character(outputyear)]
AdjustedOutput[, paste(outputyear, "IndustryOutput", sep = "")] <- AdjustedOutput$Output * AdjustedOutput$DollarRatio
# Assign rownames and keep wanted column
To do this it is getting the CPI (gross output chain-price indices) for both the reference year (model IO data year) and the output year. Then the DollarRatio, which is denoted as &rho or "rho" in eq. 6 of the USEEIO paper, is created. In this next line, this ratio of reference year to output year is then multiplied, as in eq 5 to , by the original output year output. This effectively results in the output year output being converted into reference year dollars.
In our example here is what we get
df <- subset(AdjustedOutput,SectorCode=="221100/US")
df
# SectorCode Output 2012 2019 DollarRatio
#22 221100/US 4.39108e+11 100 111.9201 0.8934946
rho <- df$DollarRatio
The rho of 2012:2019 USD ~0.89. So we just multiply this to convert a 2019 USD value to 2012 USD as done in adjusted output (the 2019 USD unit cancels out).
x_elec_adj <- x_elec * rho
x_elec_adj
#[1] 392340608301
So x_elec_adj is our 2019 electricity output converted into 2012 USD.
Returning now to generateFlowtoDollarCoefficient() where the coefficient is yet to be created:
lns 73,80 SatelliteFunctions.R
Sattable_USEEIO_wOutput <- merge(sattable, Output_adj, by.x = "Sector", by.y = 0, all.x = TRUE)
...
Sattable_USEEIO_wOutput$FlowAmount <- Sattable_USEEIO_wOutput$FlowAmount/Sattable_USEEIO_wOutput[, outputcolname]
The adjusted output df is merged back with the satellite table. Then, the original flow total by sector from that output year is divided by the adjusted output value. This is done by row arithimatically but is equivalent to the matrix algebra formular in Eq 4 in the paper.
In our example, we can do this for the single values we;ve saved to to calculate the electric power CO2 coefficient in CO2/2012 USD
CO2_elec_kg_per_2012USD <- CO2_total/x_elec_adj
CO2_elec_kg_per_2012USD
[1] 3.395897
And we can check that this value is the same in running the useeior code in buildModel for the CbS
#check this against whats in the model CbS
model$CbS <- generateCbSfromTbSandModel(model)
df <- subset(model$CbS,(Flowable=="Carbon dioxide" & Sector=="221100"), select=c("Flowable","FlowAmount","Unit","SectorName"))
df
#Flowable FlowAmount Unit SectorName
#71 Carbon dioxide 3.395897 kg Electric power generation, transmission, and distribution
It is the same.
The buildModel's constructEEIOMatrices() proceeds to create the B matrix from that CbS.
Those values now are using the same denominator in USD 2012 to the direct and associated total requirements matrices, with values in USD 2012/USD 2012.
@WesIngwersen thank you so much for laying out the detailed steps, and you are correct - the final coefficients in USEEIO models are in 2012 USD. This step in
adjustOutputbyCPI
is critical for understanding what adjustment has been made to output, and I overlooked it when talking to Yi in the first place. Using your 2019 model example, theOutput
here is output in 2019 nominal value. By applying the CPI adjustment, it is converted to 2012 nominal value and is carried over in subsequent model-building steps.