Gams makes aggregating tables quite easy. Imagine you a table with data for 100 sectors but you want to run your model in the testing phase for an aggregation of these sectors (e.g. an aggregate the 100 sectors to the three sector groups “agriculture”, “industry”, and “services”). This is a typical situation in CGE (computable general equilibrium modeling): you have a social accounting matrix for your country and you want to start with a simple model having only a few sectors, one household, no taxes, and no government).
In Gams you simply introduce a mapping that maps the 100 sectors to the three groups. Once you have this mapping, producing the aggregated table of the data is just a one-liner.
What follows is the code to import a table from Excel, aggregate the table and export it.The Excel table is called sam.xlsx and contains the following table in sheet1:
The following file “data.gms” produces an aggregated table:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
Sets alle all elements of the SAM table / sec1, sec2, capital, labor, RA / ; set agg 'aggregated set with just one sector' /sec, RA, capital, labor/, mapAlle_Agg(alle, agg) 'Mapping the disaggregated to the aggregated' /(sec1, sec2).sec, RA.RA, capital.capital, labor.labor/; alias(alle, aalle), (agg,aagg); * Import the full database from Excel parameter sam(alle, aalle) 'social accounting matrix'; * Create a GDX file from an Excel file: $call gdxxrw.exe sam.xlsx par=SAM rng=sheet1!b1..i6 Trace=3 CheckDate * Open the GDX, import the SAM parameter, close the GDX file $gdxin sam.gdx $loaddc sam * Aggregate the values parameter samagg(agg,aagg) 'Aggregated sam'; samagg(agg,aagg) = sum((alle, aalle)$((mapAlle_Agg(alle, agg)) * mapAlle_Agg(aalle, aagg)), sam(alle, aalle)); display sam, samagg ; * Save the results in a file execute_unload 'agg1.gdx', samagg, agg, secagg; |
And this is the result:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
---- 34 PARAMETER sam social accounting matrix sec1 sec2 capital labor RA sec1 5.000 40.000 55.000 sec2 15.000 20.000 165.000 capital 60.000 50.000 labor 20.000 90.000 RA 110.000 110.000 ---- 34 PARAMETER samagg Aggregated sam capital labor RA sec capital 110.000 labor 110.000 RA 110.000 110.000 sec 220.000 80.000 |
You can make this procedure flexible by defining a compile-time variable, so you can have multiple aggregations (you probably want to have your data for the full table and an aggregated table). For this, we enter the following code at the beginning of the file:
1 |
$setlocal mapping agg1 |
This defines the local compile-time variable “mapping” which has the value “agg1”. When you compile/execute your file, Gams will replace %mapping% in your code with the actual value of the variable “mapping”.
We move the mapping (lines 6-11) in a separate file called “agg1.inc” and in the main file we put here instead the following line:
1 |
$include %mapping%.inc |
Gams will now replace %mapping% by “agg1” and include the file “agg1.inc”. We also change the line, where we export the results as follows, so Gams will export the results to the file “agg1.gdx”:
1 |
execute_unload '%mapping%.gdx', samagg, agg, secagg; |
Additionally, we add a mapping file with the full disaggregation (full.inc), which maps each element to itself:
1 2 3 4 5 6 7 8 |
set agg 'Aggregated elements' /sec1, sec2,RA, capital, labor/, mapAlle_Agg(alle, agg) 'Mapping' /sec1.sec1, sec2.sec2, RA.RA, capital.capital, labor.labor/; |
We now can produce a gdx with the full table by replacing “agg1” by “full” (or run the file in the command line as “gams data.gms –mapping=full”):
1 |
$setlocal mapping full |
We now will have a gdx file “full.gdx” with the full table.
Now, we can run our model code in the full disaggregated or aggregated version. For this, you will have to put the following lines at the start of your model file:
1 2 3 4 5 6 7 8 9 10 11 |
$setlocal mapping agg1 sets alle 'All elements of the SAM'; parameter sam(alle,alle) 'Social accounting matrix'; alias(alle, aalle); $gdxin %mapping%.gdx $load alle = agg, sam=samagg |
Notice, that I revert back to the original names for the set and parameter by loading and renaming at the same time (“$load alle=agg” loads the set agg as “alle”).
In a next post, I will introduce some code to check if your mapping contains all set elements or repeats elements on both sides.