Forecasting

Capped vs. Uncapped Degree Days

February 20, 2019

In energy modeling, we often utilize spline variables to capture the non-linear relationship between consumption and temperature. These variables typically take the form of Heating Degree Days (HDD) and Cooling Degree Days (CDD). In the simplest case, a CDD variable evaluates to a positive value when temperatures exceed a critical breakpoint, while it returns a 0 otherwise. Similarly, an HDD variable evaluates to a positive value when temperatures are less than a critical breakpoint, while it returns a 0 otherwise.

Where:
AvgDB = Average Drybulb Temperature
d = date

In this example, the critical break point is 65: temperatures above 65 return positive CDD values, while temperatures below 65 return positive HDD values. Of course, 65 degrees is not necessarily the point above which cooling starts and below which heating starts—this is for illustrative purposes and these points may differ based on geography and other factors.

To extend this idea, we create multiple CDD and HDD variables, each of which have different critical breakpoints. This allows the model to capture a different weather response at different temperatures. For example:

These are ‘open-ended’ or ‘non-capped’ degree days. CDD65 returns a positive value for all temperatures above 65. CDD75 returns a positive value for all temperatures above 75. Both CDD65 and CDD75 return positive values at temperatures above 75. The following table evaluates the two CDD variables at three different temperatures: below 65 degrees, between 65 and 75, and above 75.

By way of contrast, we can create ‘capped’ degree days, which include a ceiling on their value. The following two equations are alternate yet mathematically equivalent specifications:

These two equations evaluate as follows:

  1. At temperatures below 65, the equations return 0.
  2. At temperatures between 65 and 75, the equations return a value between 0 and 10.
  3. At temperatures above 75, the equations return 10.

To capture the effect of temperatures above 75, we will need another variable. The highest CDD variable must remain ‘open ended’ to capture all possible temperatures above the breakpoint. In other words, this variable is specified identically to the uncapped version.

The following table evaluates the two CDD variables at three different temperatures: below 65 degrees, between 65 and 75, and above 75.

In this simple example, the only difference between the values in Table 1and Table 2 is the value for the first CDD at 76 degrees. In the uncapped version, CDD65 evaluates to 11 and it evaluates to 10 in the uncapped version.

This raises the following question: does it matter if I use capped or non-capped degree days in my model?

To answer this question, we can evaluate two daily energy models. The models include a constant term, a trend, two CDD variables and two HDD variables:

The following figure presents the coefficients from each of the two models, with the non-capped degree days on the left and the capped degree days on the right. The first thing to observe is that the coefficients are the same for the constant term, the trend variable, CDD65 and HDD60. However, the action happens in the extreme degree-day variables.

In the uncapped model, the effect of the extreme degree days also incorporates the effects of the less extreme values. In this example, temperatures above 75 are incorporated in both the CDD65 and CDD75 variable, wherein the coefficient on CDD75 represents the marginal effect of those observations. That means the net effect of a temperature above 75 is the sum of the coefficient for CDD65 and CDD75. Similarly, the effects of the HDD50 also incorporates the effects of the HDD60.

In the uncapped model, the sum of the coefficients on CDD65 and CDD75 is 25,571.0, which is exactly equivalent to the coefficient on the CDD75 in the capped model. Similarly, the sum of the coefficients on the HDD60 and HD50 variables is 7,817.7, which is exactly equivalent to the coefficient on the HDD50 in the capped model.

There are a few observations:

  • The remainder of the coefficients are identical.
  • The model statistics are identical in the two specifications.
  • These results occur in monthly models as well.

There are times, particularly with monthly models, where the uncapped degree days—primarily the extreme values—will be statistically insignificant. This occurs because there is collinearity between the degree-day variables. If there is concern about the optics of including insignificant variables in the model (e.g. from management or regulatory oversight), the capped degree days provide a solution, as they will typically be highly significant. Rest assured however, the results will be identical.

The takeaway is that you can use whichever approach you prefer – with impunity.

Feel free to download the associated MetrixND file to play with on your own.

Be sure to check out our forecasting website for all your forecasting needs at www.itron.com/forecasting.

Wystąpił błąd podczas przetwarzania szablonu.
The following has evaluated to null or missing:
==> authorContent.contentFields  [in template "44616#44647#114455" at line 9, column 17]

----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
	- Failed at: contentFields = authorContent.content...  [in template "44616#44647#114455" at line 9, column 1]
----
1<#assign 
2	webContentData = jsonFactoryUtil.createJSONObject(author.getData()) 
3	classPK = webContentData.classPK 
4/> 
5 
6<#assign 
7authorContent = restClient.get("/headless-delivery/v1.0/structured-contents/" + classPK + "?fields=contentFields%2CfriendlyUrlPath%2CtaxonomyCategoryBriefs") 
8contentFields = authorContent.contentFields 
9categories=authorContent.taxonomyCategoryBriefs 
10authorContentData = jsonFactoryUtil.createJSONObject(authorContent) 
11friendlyURL = authorContentData.friendlyUrlPath 
12authorCategoryId = "0" 
13/> 
14 
15<#list contentFields as contentField > 
16   <#assign  
17	 contentFieldData = jsonFactoryUtil.createJSONObject(contentField)  
18	 name = contentField.name 
19	 /> 
20	 <#if name == 'authorImage'> 
21	    <#if (contentField.contentFieldValue.image)??> 
22	        <#assign authorImageURL = contentField.contentFieldValue.image.contentUrl />	 
23			</#if> 
24	 </#if> 
25	 <#if name == 'authorName'> 
26	    <#assign authorName = contentField.contentFieldValue.data /> 
27			<#list categories as category > 
28         <#if authorName == category.taxonomyCategoryName> 
29				     <#assign authorCategoryId = category.taxonomyCategoryId /> 
30				 </#if> 
31      </#list> 
32	 </#if> 
33	 <#if name == 'authorDescription'> 
34	    <#assign authorDescription = contentField.contentFieldValue.data /> 
35			 
36	 </#if> 
37	  
38	 <#if name == 'authorJobTitle'> 
39	    <#assign authorJobTitle = contentField.contentFieldValue.data /> 
40			 
41	 </#if> 
42 
43</#list> 
44 
45<div class="blog-author-info"> 
46	<#if authorImageURL??> 
47		<img class="blog-author-img" id="author-image" src="${authorImageURL}" alt="" /> 
48	</#if> 
49	<#if authorName??> 
50		<#if authorName != ""> 
51			<p class="blog-author-name">By <a id="author-detail-page" href="/w/${friendlyURL}?filter_category_552298=${authorCategoryId}"><span id="author-full-name">${authorName}</span></a></p> 
52			<hr /> 
53		</#if> 
54	</#if> 
55	<#if authorJobTitle??> 
56		<#if authorJobTitle != ""> 
57			<p class="blog-author-title" id="author-job-title" >${authorJobTitle}</p> 
58			<hr /> 
59		</#if> 
60	</#if> 
61	<#if authorDescription??> 
62		<#if authorDescription != "" && authorDescription != "null" > 
63			<p class="blog-author-desc" id="author-job-desc">${authorDescription}</p> 
64			<hr /> 
65		</#if> 
66	</#if> 
67</div>