I used data from rdsm.com/stats. This is more of an exploratory document.

epa_Data = read.csv("https://docs.google.com/spreadsheets/d/1-2VkGfZoijfjMHblG5gf31FxUJN3KpmbuBqlHQAO1PU/gviz/tq?tqx=out:csv&sheet=NFL", header = TRUE, row.names = 1) #csvData




plot(c(1999:2021), epa_Data[6,], type = "l", col= "#ff3c00", main = "BROWNS EPA/Play by Season", lwd = 3, xlab = "Year", ylab = "EPA/Play")
lines(c(1999:2021), epa_Data[33,], col = "black", lwd = 3)
legend("topleft", legend=c("BROWNS", "Average"), 
       col=c("#ff3c00", "black"),lwd=c(3, 3))

plot(c(1999:2021), epa_Data[23,], type = "l", col= "#bcc4ca", main = "Patriots Off. EPA/Play by Season", lwd = 3, xlab = "Year", ylab = "EPA/Play")
lines(c(1999:2021), epa_Data[33,], col = "black", lwd = 3)
legend("topleft", legend=c("Patriots", "Average"), 
       col=c("#bcc4ca", "black"),lwd=c(3, 3))

row_Of = function(rowNum){
  totalnums = c();
  for (i in 1:23){
    totalnums[i] = epa_Data[rowNum, i]
  }
  return(totalnums)
  
}

averages = c()
for (j in 1:32){
  averages[j] = mean(row_Of(j), na.rm = TRUE)
}

averages
##  [1] -0.025956522 -0.078739130 -0.021565217 -0.040521739  0.009521739
##  [6] -0.084260870 -0.031043478 -0.065304348  0.041304348  0.039608696
## [11]  0.061565217  0.008565217 -0.047695652  0.004956522 -0.002826087
## [16] -0.030347826 -0.023869565 -0.042608696 -0.054652174 -0.061173913
## [21]  0.066608696 -0.031869565  0.074782609 -0.036086957 -0.030739130
## [26] -0.020043478  0.044608696  0.015521739  0.019043478 -0.026050000
## [31] -0.015913043  0.003304348
downContinueCount = 0
  downReboundCount = 0
  upContinueCount = 0
  upFallCount = 0
  upGrowth = c()
  downGrowth = c()
row_Of = function(rowNum){
  totalnums = c();
  for (i in 1:23){
    totalnums[i] = epa_Data[rowNum, i]
  }
  return(totalnums)
  
}  
  
for (r in 1:32)  {
  team = row_Of(r)
    for (y in 1:21)  {
      if (!is.na(team[y]) && !is.na(team[y+1]) && !is.na(team[y+2])){
      if (team[y + 1] > team[y]){
        upGrowth[length(upGrowth) + 1] = team[y + 2] - team[y + 1]
        if (team[y + 2] > team[y + 1]){
          upContinueCount = upContinueCount + 1
          } else if (team[y + 2] < team[y+1])  {
            upFallCount = upFallCount + 1
            }

        } else if (team[y+1] < team[y]){
          downGrowth[length(downGrowth) + 1] = team[y + 2] - team[y + 1]
          if (team[y + 2] > team[y + 1])  {
            downReboundCount= downReboundCount +1
            } else if (team[y + 2] < team[y + 1])  {
              downContinueCount = downContinueCount + 1
    }
    
  }
}
}
}  
  
  downContinueCount
## [1] 111
  downReboundCount
## [1] 212
  mean(upGrowth)
## [1] -0.0295614
  mean(downGrowth)
## [1] 0.03555556
  var(upGrowth)
## [1] 0.007490611
  var(downGrowth)
## [1] 0.007682452
upContinueCount
## [1] 120
upFallCount
## [1] 220

Of teams who improved offensively from one year to the next, only \(\frac{1}{3}\) continued to have a better season.

downContinueCount
## [1] 111
  downReboundCount
## [1] 212

On the other side, “regressing to the mean” was even more prevalent, as only 22% of teams who had a worse offensive year continued to have a worse year the season after. A potential reason for the disparity between teams who improve and worsen is that the overall average EPA/play does increase over time.

mean(upGrowth)
## [1] -0.0295614
median(upGrowth)
## [1] -0.027
mean(upGrowth > .1)
## [1] 0.06432749
mean(upGrowth < -.1)
## [1] 0.2105263
hist(upGrowth)

mean(downGrowth)
## [1] 0.03555556
median(downGrowth)
## [1] 0.029
mean(downGrowth > .1)
## [1] 0.2376543
mean(downGrowth < -.1)
## [1] 0.0617284
hist(downGrowth)