---
title: "Measuring RPS stringency"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Measuring RPS stringency}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4)
has_keys <- nzchar(Sys.getenv("EIA_API_KEY")) && nzchar(Sys.getenv("BEA_API_KEY"))
```

```{r setup}
library(rpspanel)
```

Many studies code a Renewable Portfolio Standard (RPS) as a yes/no dummy.
Real policies differ in targets, timelines, covered utilities, eligible
resources, carve-outs and out-of-state flexibility. `rps_stringency()` turns
coded rules into comparable annual measures.

## The rule coding

```{r rules}
rules <- rps_rules()
rules
head(rules$targets)
```

Each RPS state has one row in `rules$rules` (enactment and first compliance
year, target type, coverage share, design features, sources and notes) and
one row per legal target in `rules$targets`. States missing from the coding
are *not yet coded*, and get `NA` rather than zero.

> **Status.** The bundled coding covers all 50 states and DC. Rows marked
> `verified = TRUE` have been checked against the statute, the DSIRE
> program page and the LBNL RPS & CES data, with sources in the `source`
> and `notes` columns. Single-number simplifications (one coverage share,
> one schedule for states with utility-specific targets) are described in
> `notes`. Please report corrections. You can supply your own coding with
> `rps_rules(rules_path = ..., targets_path = ...)`.

## Methods

| method | column(s) | definition |
|---|---|---|
| `adoption` | `rps_adoption` | 1 if an RPS is in force |
| `nominal` | `rps_nominal` | required share of sales, interpolated between legal targets |
| `coverage_adjusted` | `rps_coverage_adj` | nominal x share of sales covered |
| `incremental` | `rps_incremental`, `rps_baseline_share` | coverage-adjusted requirement minus the existing renewable share at enactment (Yin and Powers 2010) |
| `flexibility` | `rps_oos_rec`, `rps_carveout`, `rps_acp` | design indicators while an RPS is in force |

```{r stringency}
s <- rps_stringency(2000:2030, states = c("CA", "OR", "WA", "NC", "MA"))
head(s[s$state == "OR", ], 15)
```

### Linear or step interpolation

Legal schedules often step (for example Washington: 3% from 2012, 9% from
2016, 15% from 2020). `interpolation = "step"` follows the schedule exactly;
`"linear"` (the default) spreads the ramp evenly between target years.

```{r interp}
lin  <- rps_stringency(2010:2022, "WA", method = "nominal")
step <- rps_stringency(2010:2022, "WA", method = "nominal", interpolation = "step")
plot(lin$year, lin$rps_nominal, type = "l", ylab = "Required share", xlab = "",
     main = "Washington RPS")
lines(step$year, step$rps_nominal, type = "s", lty = 2)
legend("topleft", c("linear", "step"), lty = 1:2, bty = "n")
```

### Nominal requirements across states

```{r nominal-plot}
cols <- c(CA = "#1b9e77", OR = "#d95f02", WA = "#7570b3", NC = "#e7298a", MA = "#66a61e")
plot(NA, xlim = c(2000, 2030), ylim = c(0, 0.65), xlab = "",
     ylab = "Nominal requirement (share of sales)")
for (st in names(cols)) {
  d <- s[s$state == st, ]
  lines(d$year, d$rps_nominal, col = cols[st], lwd = 2)
}
legend("topleft", names(cols), col = cols, lwd = 2, bty = "n")
```

### Incremental requirement

The incremental measure subtracts what the state already produced when it
enacted the standard, separating new pressure from existing renewables.
`build_panel()` fills the baseline from EIA generation data: the renewable
share in the enactment year (or the first later year with data), measured
the same way as the target. For New York, whose targets count existing hydro,
the baseline includes hydro (about 19% in 2004, close to the 19.3% written
into its RPS order); elsewhere it is the non-hydro share. A generation-based
baseline is a weak guide for states that import most of their electricity,
such as Vermont. You can always pass your own baseline:

```{r incremental}
base <- data.frame(state = c("CA", "OR"), baseline_share = c(0.11, 0.03))
inc <- rps_stringency(c(2010, 2020, 2030), c("CA", "OR"),
                      method = c("coverage_adjusted", "incremental"),
                      baseline = base)
inc
```

`OR` has `NA` coverage-adjusted and incremental values because its coverage
share is not yet coded.

### Capacity-based standards (Texas and Iowa)

Texas and Iowa set their standards in megawatts rather than as a share of
sales. `rps_stringency()` converts them, like Berkeley Lab does, into the
share of covered sales the capacity would supply:
`MW x capacity factor x 8,760 hours / covered sales`. The capacity factor
defaults to 0.33 (typical of wind) and can be changed. `build_panel()`
supplies retail sales automatically; with `rps_stringency()` you pass them:

```{r capacity}
tx_sales <- data.frame(state = "TX", year = c(2010, 2015), sales_gwh = c(358000, 380000))
rps_stringency(c(2010, 2015), "TX", method = "nominal", sales = tx_sales)
rps_stringency(c(2010, 2015), "TX", method = "nominal", sales = tx_sales,
               capacity_factor = 0.4)
```

## A template for Yin and Powers (2010)-style regressions

Yin and Powers (2010) regress the non-hydro renewable share of generation on
the incremental requirement with state and year fixed effects. The template
below shows the workflow; it is not a replication, because their sample,
coding and controls differ from the bundled starter coding.

```{r yp, eval = FALSE}
library(fixest)
p <- build_panel(years = 2001:2022,
                 vars = c("re_share_nonhydro", "rps_incremental", "rps_adoption",
                          "gdp_real_pc", "elec_price_real"))
feols(re_share_nonhydro ~ rps_incremental + log(gdp_real_pc) + elec_price_real |
        state + year,
      data = as_pdata(p, "fixest"), cluster = ~state)
```

## Reference

Yin, H., & Powers, N. (2010). Do state renewable portfolio standards promote
in-state renewable generation? *Energy Policy*, 38(2), 1140-1149.
