pySEQTarget 0.13.0__tar.gz → 0.13.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/PKG-INFO +2 -2
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/SEQopts.py +5 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/SEQuential.py +10 -3
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget.egg-info/PKG-INFO +2 -2
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pyproject.toml +2 -1
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_expansion.py +37 -1
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/LICENSE +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/README.md +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/SEQoutput.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/__init__.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/analysis/__init__.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/analysis/_hazard.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/analysis/_outcome_fit.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/analysis/_risk_estimates.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/analysis/_subgroup_fit.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/analysis/_survival_pred.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/data/__init__.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/error/__init__.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/error/_check_separation.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/error/_data_checker.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/error/_param_checker.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/expansion/__init__.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/expansion/_binder.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/expansion/_diagnostics.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/expansion/_dynamic.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/expansion/_mapper.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/expansion/_selection.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/__init__.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_bootstrap.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_col_string.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_fix_categories.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_format_time.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_offloader.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_output_files.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_pad.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_predict_model.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_prepare_data.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/initialization/__init__.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/initialization/_censoring.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/initialization/_denominator.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/initialization/_numerator.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/initialization/_outcome.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/plot/__init__.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/plot/_survival_plot.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/weighting/__init__.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/weighting/_weight_bind.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/weighting/_weight_data.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/weighting/_weight_fit.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/weighting/_weight_offload.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/weighting/_weight_pred.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/weighting/_weight_stats.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget.egg-info/SOURCES.txt +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget.egg-info/dependency_links.txt +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget.egg-info/requires.txt +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget.egg-info/top_level.txt +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/setup.cfg +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_accessor.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_check_separation.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_coefficients.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_covariates.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_fix_categories.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_followup_options.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_hazard.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_no_variation.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_offload.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_parallel.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_plot.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_reproducibility.py +0 -0
- {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_survival.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pySEQTarget
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.2
|
|
4
4
|
Summary: Sequentially Nested Target Trial Emulation
|
|
5
5
|
Author-email: Ryan O'Dea <ryan.odea@psi.ch>, Alejandro Szmulewicz <aszmulewicz@hsph.harvard.edu>, Tom Palmer <tom.palmer@bristol.ac.uk>, Miguel Hernán <mhernan@hsph.harvard.edu>
|
|
6
|
-
Maintainer-email: Ryan O'Dea <ryan.odea@psi.ch>
|
|
6
|
+
Maintainer-email: Ryan O'Dea <ryan.odea@psi.ch>, Tom Palmer <remlapmot@hotmail.com>
|
|
7
7
|
License: MIT
|
|
8
8
|
Project-URL: Homepage, https://github.com/CausalInference/pySEQTarget
|
|
9
9
|
Project-URL: Repository, https://github.com/CausalInference/pySEQTarget
|
|
@@ -36,6 +36,9 @@ class SEQopts:
|
|
|
36
36
|
:type excused: bool
|
|
37
37
|
:param excused_colnames: Column names (at the same length of treatment_level) specifying excused conditions, default ``[]``
|
|
38
38
|
:type excused_colnames: List[str]
|
|
39
|
+
:param expand_only: If True, ``SEQuential.expand()`` returns the expanded dataset and skips weighting,
|
|
40
|
+
modelling, and survival steps
|
|
41
|
+
:type expand_only: bool
|
|
39
42
|
:param followup_class: Boolean to force followup values to be treated as classes
|
|
40
43
|
:type followup_class: bool
|
|
41
44
|
:param followup_include: Boolean to force regular followup values into model covariates
|
|
@@ -121,6 +124,7 @@ class SEQopts:
|
|
|
121
124
|
denominator: Optional[str] = None
|
|
122
125
|
excused: bool = False
|
|
123
126
|
excused_colnames: List[str] = field(default_factory=lambda: [])
|
|
127
|
+
expand_only: bool = False
|
|
124
128
|
followup_class: bool = False
|
|
125
129
|
followup_include: bool = True
|
|
126
130
|
followup_max: int = None
|
|
@@ -161,6 +165,7 @@ class SEQopts:
|
|
|
161
165
|
def _validate_bools(self):
|
|
162
166
|
bools = [
|
|
163
167
|
"excused",
|
|
168
|
+
"expand_only",
|
|
164
169
|
"followup_class",
|
|
165
170
|
"followup_include",
|
|
166
171
|
"followup_spline",
|
|
@@ -107,9 +107,11 @@ class SEQuential:
|
|
|
107
107
|
_param_checker(self)
|
|
108
108
|
_data_checker(self)
|
|
109
109
|
|
|
110
|
-
def expand(self)
|
|
110
|
+
def expand(self):
|
|
111
111
|
"""
|
|
112
|
-
Creates the sequentially nested, emulated target trial structure
|
|
112
|
+
Creates the sequentially nested, emulated target trial structure.
|
|
113
|
+
If ``expand_only`` is set in parameters, returns the expanded dataset as a
|
|
114
|
+
:class:`polars.DataFrame` and skips all subsequent analysis steps.
|
|
113
115
|
"""
|
|
114
116
|
start = time.perf_counter()
|
|
115
117
|
kept = [
|
|
@@ -160,7 +162,9 @@ class SEQuential:
|
|
|
160
162
|
pl.col(self.id_col).cast(pl.Utf8).alias(self.id_col)
|
|
161
163
|
)
|
|
162
164
|
|
|
163
|
-
if self.method
|
|
165
|
+
if self.method == "dose-response" or (
|
|
166
|
+
self.method == "censoring" and not self.expand_only
|
|
167
|
+
):
|
|
164
168
|
_dynamic(self)
|
|
165
169
|
if self.selection_random:
|
|
166
170
|
_random_selection(self)
|
|
@@ -169,6 +173,9 @@ class SEQuential:
|
|
|
169
173
|
end = time.perf_counter()
|
|
170
174
|
self._expansion_time = _format_time(start, end)
|
|
171
175
|
|
|
176
|
+
if self.expand_only:
|
|
177
|
+
return self.DT
|
|
178
|
+
|
|
172
179
|
def bootstrap(self, **kwargs) -> None:
|
|
173
180
|
"""
|
|
174
181
|
Internally sets up bootstrapping - creating a list of IDs to use per iteration
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pySEQTarget
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.2
|
|
4
4
|
Summary: Sequentially Nested Target Trial Emulation
|
|
5
5
|
Author-email: Ryan O'Dea <ryan.odea@psi.ch>, Alejandro Szmulewicz <aszmulewicz@hsph.harvard.edu>, Tom Palmer <tom.palmer@bristol.ac.uk>, Miguel Hernán <mhernan@hsph.harvard.edu>
|
|
6
|
-
Maintainer-email: Ryan O'Dea <ryan.odea@psi.ch>
|
|
6
|
+
Maintainer-email: Ryan O'Dea <ryan.odea@psi.ch>, Tom Palmer <remlapmot@hotmail.com>
|
|
7
7
|
License: MIT
|
|
8
8
|
Project-URL: Homepage, https://github.com/CausalInference/pySEQTarget
|
|
9
9
|
Project-URL: Repository, https://github.com/CausalInference/pySEQTarget
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pySEQTarget"
|
|
7
|
-
version = "0.13.
|
|
7
|
+
version = "0.13.2"
|
|
8
8
|
description = "Sequentially Nested Target Trial Emulation"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -30,6 +30,7 @@ authors = [
|
|
|
30
30
|
|
|
31
31
|
maintainers = [
|
|
32
32
|
{name = "Ryan O'Dea", email = "ryan.odea@psi.ch"},
|
|
33
|
+
{name = "Tom Palmer", email = "remlapmot@hotmail.com"},
|
|
33
34
|
]
|
|
34
35
|
|
|
35
36
|
dependencies = [
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import polars as pl
|
|
2
|
+
from polars.testing import assert_frame_equal
|
|
2
3
|
|
|
3
|
-
from pySEQTarget import SEQuential
|
|
4
|
+
from pySEQTarget import SEQopts, SEQuential
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
def _make_model(data):
|
|
@@ -90,3 +91,38 @@ def test_expansion_truncates_each_trial_independently():
|
|
|
90
91
|
|
|
91
92
|
# Trial 1 starts at time=1, outcome at time=3 → followup 0,1,2
|
|
92
93
|
assert sorted(trial_1["followup"].to_list()) == [0, 1, 2]
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def test_expand_only_returns_expanded_dataframe():
|
|
97
|
+
"""expand_only=True should return the expanded DataFrame directly and the
|
|
98
|
+
return value should equal self.DT from a standard expand() call."""
|
|
99
|
+
data = pl.DataFrame(
|
|
100
|
+
{
|
|
101
|
+
"ID": [1, 1, 1, 1, 1],
|
|
102
|
+
"time": [0, 1, 2, 3, 4],
|
|
103
|
+
"eligible": [1, 0, 0, 0, 0],
|
|
104
|
+
"treatment": [0, 1, 0, 1, 0],
|
|
105
|
+
"outcome": [0, 0, 0, 0, 0],
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
model_only = SEQuential(
|
|
110
|
+
data,
|
|
111
|
+
id_col="ID",
|
|
112
|
+
time_col="time",
|
|
113
|
+
eligible_col="eligible",
|
|
114
|
+
treatment_col="treatment",
|
|
115
|
+
outcome_col="outcome",
|
|
116
|
+
time_varying_cols=[],
|
|
117
|
+
fixed_cols=[],
|
|
118
|
+
parameters=SEQopts(expand_only=True),
|
|
119
|
+
)
|
|
120
|
+
result = model_only.expand()
|
|
121
|
+
|
|
122
|
+
assert isinstance(result, pl.DataFrame)
|
|
123
|
+
assert_frame_equal(result, model_only.DT)
|
|
124
|
+
|
|
125
|
+
model_full = _make_model(data)
|
|
126
|
+
model_full.expand()
|
|
127
|
+
|
|
128
|
+
assert_frame_equal(result, model_full.DT)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|