Skip to content

Commit fb943f9

Browse files
Merge pull request #8 from Techtonique/try-improve-rpy2-usage
Align with R version 0.6.2
2 parents a05f80f + 9e0babd commit fb943f9

File tree

20 files changed

+433
-312
lines changed

20 files changed

+433
-312
lines changed

CHANGES.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
# version 0.6.2
2+
3+
- Add Block Bootstrap to `ridge2f` and `basicf`
4+
- Add external regressors to `ridge2f`
5+
- Add clustering with _K-Means_ and hierarchical clustering to `ridge2f`
6+
- Install R or rpy2 if necessary (? weird)
7+
- Refactor code for `rpy2` and R imports
8+
19
# version 0.6.1
210

311
- Reduce number of required packages depencies

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ dist: clean ## builds source and wheel package
7979
ls -l dist
8080

8181
install: clean ## install the package to the active Python's site-packages
82-
python setup.py install
82+
python3 -m pip install .
8383

8484
build-site: docs ## put docs website in a directory
8585
cd docs&&mkdocs build

ahead/ARMAGARCH/ArmaGarch.py

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,9 @@
1-
import os
21
import numpy as np
3-
import pandas as pd
4-
5-
import rpy2.robjects as robjects
6-
import rpy2.robjects.packages as rpackages
7-
from rpy2.robjects.packages import importr
8-
from rpy2.robjects import FloatVector
9-
from datetime import datetime
10-
from rpy2.robjects.packages import importr
11-
from rpy2.robjects.vectors import StrVector
2+
from .. import config
123

134
from ..utils import univariate as uv
145
from ..utils import unimultivariate as umv
156

16-
required_packages = ["ahead"] # list of required R packages
17-
18-
if all(rpackages.isinstalled(x) for x in required_packages):
19-
check_packages = True # True if packages are already installed
20-
else:
21-
check_packages = False # False if packages are not installed
22-
23-
if check_packages == False: # Not installed? Then install.
24-
25-
packages_to_install = [
26-
x for x in required_packages if not rpackages.isinstalled(x)
27-
]
28-
29-
if len(packages_to_install) > 0:
30-
base = importr("base")
31-
utils = importr("utils")
32-
base.options(
33-
repos=base.c(
34-
techtonique="https://techtonique.r-universe.dev",
35-
CRAN="https://cloud.r-project.org",
36-
)
37-
)
38-
utils.install_packages(StrVector(packages_to_install))
39-
check_packages = True
40-
41-
42-
stats = importr("stats")
43-
ahead = importr("ahead")
44-
45-
467
class ArmaGarch(object):
478
""" ARMA(1, 1)-GARCH(1, 1) forecasting (with simulation)
489
@@ -112,7 +73,12 @@ def __init__(
11273
dist = "student",
11374
seed = 123,
11475
date_formatting="original",
115-
):
76+
):
77+
if not config.R_IS_INSTALLED:
78+
raise ImportError("R is not installed! \n" + config.USAGE_MESSAGE)
79+
80+
if not config.RPY2_IS_INSTALLED:
81+
raise ImportError(config.RPY2_ERROR_MESSAGE + config.USAGE_MESSAGE)
11682

11783
self.h = h
11884
self.level = level
@@ -121,6 +87,7 @@ def __init__(
12187
self.dist = dist
12288
self.seed = seed
12389
self.date_formatting = date_formatting
90+
self.input_df = None
12491

12592
self.fcast_ = None
12693
self.averages_ = None
@@ -154,7 +121,7 @@ def forecast(self, df):
154121

155122
y = uv.compute_y_ts(df=self.input_df, df_frequency=frequency)
156123

157-
self.fcast_ = ahead.armagarchf(
124+
self.fcast_ = config.AHEAD_PACKAGE.armagarchf(
158125
y=y,
159126
h=self.h,
160127
level=self.level,

ahead/Basic/BasicForecaster.py

Lines changed: 26 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,10 @@
1-
import os
21
import numpy as np
3-
import pandas as pd
4-
5-
from rpy2.robjects.packages import importr
6-
from rpy2.robjects import FloatVector, numpy2ri
7-
import rpy2.robjects as robjects
8-
import rpy2.robjects.packages as rpackages
9-
from datetime import datetime
10-
from rpy2.robjects.vectors import StrVector
2+
from .. import config
113

124
from ..utils import multivariate as mv
135
from ..utils import unimultivariate as umv
146

15-
required_packages = ["ahead"] # list of required R packages
16-
17-
if all(rpackages.isinstalled(x) for x in required_packages):
18-
check_packages = True # True if packages are already installed
19-
else:
20-
check_packages = False # False if packages are not installed
21-
22-
if check_packages == False: # Not installed? Then install.
23-
24-
packages_to_install = [
25-
x for x in required_packages if not rpackages.isinstalled(x)
26-
]
27-
28-
if len(packages_to_install) > 0:
29-
base = importr("base")
30-
utils = importr("utils")
31-
base.options(
32-
repos=base.c(
33-
techtonique="https://techtonique.r-universe.dev",
34-
CRAN="https://cloud.r-project.org",
35-
)
36-
)
37-
utils.install_packages(StrVector(packages_to_install))
38-
check_packages = True
39-
40-
base = importr("base")
41-
stats = importr("stats")
42-
ahead = importr("ahead")
43-
44-
45-
class BasicForecaster(object):
7+
class BasicForecaster():
468
"""Basic forecasting functions for multivariate time series (mean, median, random walk)
479
4810
Parameters:
@@ -60,6 +22,9 @@ class BasicForecaster(object):
6022
Type of prediction interval (currently "gaussian",
6123
or "bootstrap")
6224
25+
block_length: an integer
26+
length of block for multivariate circular block bootstrap (`type_pi == blockbootstrap`)
27+
6328
B: an integer;
6429
Number of bootstrap replications for `type_pi == bootstrap`
6530
@@ -88,7 +53,7 @@ class BasicForecaster(object):
8853
mean_: a numpy array
8954
contains series mean forecast as a numpy array
9055
91-
lower_: a numpy array
56+
lower_: a numpy array
9257
contains series lower bound forecast as a numpy array
9358
9459
upper_: a numpy array
@@ -131,27 +96,37 @@ def __init__(
13196
level=95,
13297
method="mean",
13398
type_pi="gaussian",
99+
block_length=5,
134100
B=100,
135101
date_formatting="original",
136102
seed=123,
137103
):
138104

105+
if not config.R_IS_INSTALLED:
106+
raise ImportError("R is not installed! \n" + config.USAGE_MESSAGE)
107+
108+
if not config.RPY2_IS_INSTALLED:
109+
raise ImportError(config.RPY2_ERROR_MESSAGE + config.USAGE_MESSAGE)
110+
139111
self.h = h
140112
self.level = level
141113
self.method = method
142114
self.type_pi = type_pi
115+
self.block_length = block_length
143116
self.B = B
144117
self.date_formatting = date_formatting
118+
self.input_df = None
145119
self.seed = seed
146120

121+
self.fcast_ = None
147122
self.averages_ = None
148123
self.ranges_ = None
149124
self.output_dates_ = []
150125
self.mean_ = None
151126
self.lower_ = None
152127
self.upper_ = None
153-
self.result_df_s_ = None
154-
self.sims_ = None
128+
self.result_dfs_ = None
129+
self.sims_ = None
155130

156131
def forecast(self, df):
157132
"""Forecasting method from `BasicForecaster` class
@@ -164,7 +139,7 @@ def forecast(self, df):
164139
"""
165140

166141
self.input_df = df
167-
n_series = len(df.columns)
142+
n_series = len(df.columns)
168143

169144
# obtain dates 'forecast' -----
170145

@@ -175,12 +150,17 @@ def forecast(self, df):
175150
# obtain time series forecast -----
176151

177152
y = mv.compute_y_mts(self.input_df, frequency)
178-
self.fcast_ = ahead.basicf(
153+
154+
if self.type_pi is "blockbootstrap":
155+
assert self.block_length is not None, "For `type_pi == 'blockbootstrap'`, `block_length` must be not None"
156+
157+
self.fcast_ = config.AHEAD_PACKAGE.basicf(
179158
y,
180159
h=self.h,
181160
level=self.level,
182161
method=self.method,
183162
type_pi=self.type_pi,
163+
block_length=self.block_length,
184164
B=self.B,
185165
seed=self.seed,
186166
)
@@ -208,7 +188,7 @@ def forecast(self, df):
208188
for i in range(n_series)
209189
)
210190

211-
if self.type_pi == "bootstrap":
191+
if self.type_pi == "bootstrap" or self.type_pi == "blockbootstrap":
212192
self.sims_ = tuple(
213193
np.asarray(self.fcast_.rx2["sims"][i]) for i in range(self.B)
214194
)

ahead/DynamicRegressor/DynamicRegressor.py

Lines changed: 12 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,10 @@
1-
import os
21
import numpy as np
3-
import pandas as pd
2+
from .. import config
43

5-
import rpy2.robjects as robjects
6-
import rpy2.robjects.packages as rpackages
7-
from rpy2.robjects.packages import importr
8-
from rpy2.robjects import FloatVector
9-
from datetime import datetime
10-
from rpy2.robjects.vectors import StrVector
11-
12-
from ..utils import univariate as uv
4+
from ..utils import univariate as uv
135
from ..utils import unimultivariate as umv
146

15-
required_packages = ["ahead"] # list of required R packages
16-
17-
if all(rpackages.isinstalled(x) for x in required_packages):
18-
check_packages = True # True if packages are already installed
19-
else:
20-
check_packages = False # False if packages are not installed
21-
22-
if check_packages == False: # Not installed? Then install.
23-
24-
packages_to_install = [
25-
x for x in required_packages if not rpackages.isinstalled(x)
26-
]
27-
28-
if len(packages_to_install) > 0:
29-
base = importr("base")
30-
utils = importr("utils")
31-
base.options(
32-
repos=base.c(
33-
techtonique="https://techtonique.r-universe.dev",
34-
CRAN="https://cloud.r-project.org",
35-
)
36-
)
37-
utils.install_packages(StrVector(packages_to_install))
38-
check_packages = True
39-
40-
stats = importr("stats")
41-
ahead = importr("ahead")
42-
43-
44-
class DynamicRegressor(object):
7+
class DynamicRegressor():
458
"""Dynamic Regression Model adapted from R's `forecast::nnetar`
469
4710
Parameters:
@@ -112,10 +75,17 @@ class DynamicRegressor(object):
11275

11376
def __init__(self, h=5, level=95, type_pi="E", date_formatting="original"):
11477

78+
if not config.R_IS_INSTALLED:
79+
raise ImportError("R is not installed! \n" + config.USAGE_MESSAGE)
80+
81+
if not config.RPY2_IS_INSTALLED:
82+
raise ImportError(config.RPY2_ERROR_MESSAGE + config.USAGE_MESSAGE)
83+
11584
self.h = h
11685
self.level = level
11786
self.type_pi = type_pi
11887
self.date_formatting = date_formatting
88+
self.input_df = None
11989

12090
self.fcast_ = None
12191
self.averages_ = None
@@ -136,7 +106,7 @@ def forecast(self, df):
136106
137107
"""
138108

139-
self.input_df = df
109+
self.input_df = df
140110

141111
# obtain dates 'forecast' -----
142112

@@ -148,7 +118,7 @@ def forecast(self, df):
148118

149119
y = uv.compute_y_ts(df=self.input_df, df_frequency=frequency)
150120

151-
self.fcast_ = ahead.dynrmf(
121+
self.fcast_ = config.AHEAD_PACKAGE.dynrmf(
152122
y=y, h=self.h, level=self.level, type_pi=self.type_pi
153123
)
154124

0 commit comments

Comments
 (0)