rplexos
is an R package developed to read and analyze PLEXOS solutions. It currently supports the conversion of PLEXOS solution files into SQLite databases and functions to query those databases.
The following sections present the preferred workflow to process PLEXOS solutions with this package. We will use an example database that comes preloaded with the package. This is the location of that database in your system.
location <- location_solution_rplexos()
location
#> [1] "/Users/eibanez/Documents/Rdevelop/rplexos/inst/extdata/solution"
It is recommended to create a folder for each of your scenarios. If a run is divided in different solution files, copy them together in the same folder.
For each folder, run the following command to convert the zip file into a SQLite database.
process_folder(location)
We can also provide a vector of strings with the names of all the folders that need to be processed. For example, let us assume we have two scenarios loaded in two folders: HiWind
and HiSolar
.
process_folder(c("HiWind", "HiSolar"))
Once the databases have been processed, we can access them by first opening a connection with plexos_open
. Scenarios names can be defined at this point (if not provided, they default to the folder names).
db <- plexos_open(location, "Sc1")
Again, you can provide a vector of folders to open and a vector of scenario names.
db <- plexos_open(c("HiWind", "HiSolar"), name = c("High Wind", "High Solar"))
We can now use the db
object to query and aggregate data using the functions documented in query_master
. The list of available properties can be seen with ?query_property
.
query_property(db)
#> phase_id phase is_summary class_group class collection property unit Sc1
#> 1 4 ST 0 Production Generator Generator Capacity Curtailed MW 1
#> 2 4 ST 0 Production Generator Generator Generation MW 1
#> 3 4 ST 0 Production Generator Generator Generation Cost $ 1
#> 4 4 ST 0 Production Generator Generator Price Received $/MWh 1
#> 5 4 ST 0 Production Generator Generator Units Generating - 1
#> 6 4 ST 0 Transmission Line Line Export Limit MW 1
#> 7 4 ST 0 Transmission Line Line Flow MW 1
#> 8 4 ST 0 Transmission Line Line Import Limit MW 1
#> 9 4 ST 0 Transmission Node Node Generation MW 1
#> 10 4 ST 0 Transmission Node Node Load MW 1
#> 11 4 ST 0 Transmission Node Node Price $/MWh 1
#> 12 4 ST 0 Transmission Region Region Cost to Load $ 1
#> 13 4 ST 0 Transmission Region Region Dump Energy MW 1
#> 14 4 ST 0 Transmission Region Region Generation MW 1
#> 15 4 ST 0 Transmission Region Region Generator Pool Revenue $ 1
#> 16 4 ST 0 Transmission Region Region Load MW 1
#> 17 4 ST 0 Transmission Region Region Net Interchange MW 1
#> 18 4 ST 0 Transmission Region Region Price $/MWh 1
#> 19 4 ST 0 Transmission Region Region Settlement Surplus $ 1
#> 20 4 ST 0 Transmission Region Region Unserved Energy MW 1
#> 21 4 ST 1 Production Generator Generator Energy Curtailed GWh 1
#> 22 4 ST 1 Production Generator Generator Generation GWh 1
#> 23 4 ST 1 Production Generator Generator Generation Cost $000 1
#> 24 4 ST 1 Transmission Line Line Export Limit MW 1
#> 25 4 ST 1 Transmission Line Line Flow GWh 1
#> 26 4 ST 1 Transmission Line Line Import Limit MW 1
#> 27 4 ST 1 Transmission Region Region Cost to Load $000 1
#> 28 4 ST 1 Transmission Region Region Dump Energy GWh 1
#> 29 4 ST 1 Transmission Region Region Generation GWh 1
#> 30 4 ST 1 Transmission Region Region Generator Pool Revenue $000 1
#> 31 4 ST 1 Transmission Region Region Load GWh 1
#> 32 4 ST 1 Transmission Region Region Net Interchange GWh 1
#> 33 4 ST 1 Transmission Region Region Price $/MWh 1
#> 34 4 ST 1 Transmission Region Region Settlement Surplus $000 1
#> 35 4 ST 1 Transmission Region Region Unserved Energy GWh 1
There are also a number of queries that can be used to explore the contents of the solutions. For example, let’s take a look at the list of generators:
query_generator(db)
#> Source: local data frame [3 x 5]
#>
#> scenario position name region zone
#> 1 Sc1 1 Baseload The Region -
#> 2 Sc1 1 Peaker The Region -
#> 3 Sc1 1 Wind The Region -
The following command extract data from the “summary” tables created by PLEXOS. If selected during the solution process in PLEXOS, data is available in daily, weekly, monthly and yearly summaries. rplexos
provides a family of functions to access each type of data.
query_day(db, "Generator", "Generation")
#> Source: local data frame [3 x 8]
#>
#> scenario collection property unit name parent time value
#> 1 Sc1 Generator Generation GWh Baseload System 2015-03-14 2.38575
#> 2 Sc1 Generator Generation GWh Peaker System 2015-03-14 0.09425
#> 3 Sc1 Generator Generation GWh Wind System 2015-03-14 0.63900
For convenience, you can also use an asterisk to query all the properties in a collection:
query_day(db, "Region", "*")
#> Source: local data frame [9 x 8]
#>
#> scenario collection property unit name parent time value
#> 1 Sc1 Region Load GWh The Region System 2015-03-14 3.119000
#> 2 Sc1 Region Generation GWh The Region System 2015-03-14 3.119000
#> 3 Sc1 Region Net Interchange GWh The Region System 2015-03-14 0.000000
#> 4 Sc1 Region Unserved Energy GWh The Region System 2015-03-14 0.000000
#> 5 Sc1 Region Dump Energy GWh The Region System 2015-03-14 0.000000
#> 6 Sc1 Region Price $/MWh The Region System 2015-03-14 2.982526
#> 7 Sc1 Region Cost to Load $000 The Region System 2015-03-14 9.302500
#> 8 Sc1 Region Generator Pool Revenue $000 The Region System 2015-03-14 7.202500
#> 9 Sc1 Region Settlement Surplus $000 The Region System 2015-03-14 2.100000
You can also query the interval data. This example queries and plots the generation data:
gen <- query_interval(db, "Generator", "Generation")
ggplot(gen, aes(x = time, y = value, fill = name)) +
geom_area() +
labs(x = "Time", y = "Generation (MW)", fill = "Generator")
Similary, this example looks at nodal prices:
price <- query_interval(db, "Node", "Price")
ggplot(price, aes(x = time, y = value, color = name)) +
geom_line() +
labs(x = "Time", y = "Price ($/MW)", color = "Node")
Finally, this one looks at line flows:
price <- query_interval(db, "Line", "Flow")
ggplot(price, aes(x = time, y = value, color = name)) +
geom_line() +
labs(x = "Time", y = "Flow (MW)", color = "Generator")
rplexos
includes the capability of applying filters to both summary and interval data queries. This can be used to select the part of the data that is of interest, reducing the time it takes to query the database.
For example, the following query is limited to a given time range:
gen.time.filter <- query_interval(db, "Generator", "Generation",
time.range = c("2015-03-14 00:00:00", "2015-03-14 12:00:00"))
ggplot(gen.time.filter, aes(x = time, y = value, fill = name)) +
geom_area() +
labs(x = "Time", y = "Generation (MW)", fill = "Generator")
Similarly, the parameter filter
can be used to create other filtering conditions. The following code extracts generation data for one or two generators:
gen.gral.filter1 <- query_interval(db, "Generator", "Generation",
filter = list(name = "Baseload"))
ggplot(gen.gral.filter1, aes(x = time, y = value, fill = name)) +
geom_area() +
labs(x = "Time", y = "Generation (MW)", fill = "Generator")
gen.gral.filter2 <- query_interval(db, "Generator", "Generation",
filter = list(name = c("Baseload", "Wind")))
ggplot(gen.gral.filter2, aes(x = time, y = value, fill = name)) +
geom_area() +
labs(x = "Time", y = "Generation (MW)", fill = "Generator")
Both filtering mechanisms can be combined or used independently.
rplexos
also supports converting PLEXOS input databases (which are saved as XML file) into SQLite files. We will use an example database that comes preloaded with the package. This is the location of that database in your system.
location2 <- location_input_rplexos()
location2
#> [1] "/Users/eibanez/Documents/Rdevelop/rplexos/inst/extdata/database"
The input files are processed with the same function that is used for the solutions.
process_folder(location2)