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.
Files changed (69) hide show
  1. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/PKG-INFO +2 -2
  2. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/SEQopts.py +5 -0
  3. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/SEQuential.py +10 -3
  4. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget.egg-info/PKG-INFO +2 -2
  5. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pyproject.toml +2 -1
  6. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_expansion.py +37 -1
  7. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/LICENSE +0 -0
  8. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/README.md +0 -0
  9. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/SEQoutput.py +0 -0
  10. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/__init__.py +0 -0
  11. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/analysis/__init__.py +0 -0
  12. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/analysis/_hazard.py +0 -0
  13. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/analysis/_outcome_fit.py +0 -0
  14. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/analysis/_risk_estimates.py +0 -0
  15. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/analysis/_subgroup_fit.py +0 -0
  16. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/analysis/_survival_pred.py +0 -0
  17. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/data/__init__.py +0 -0
  18. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/error/__init__.py +0 -0
  19. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/error/_check_separation.py +0 -0
  20. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/error/_data_checker.py +0 -0
  21. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/error/_param_checker.py +0 -0
  22. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/expansion/__init__.py +0 -0
  23. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/expansion/_binder.py +0 -0
  24. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/expansion/_diagnostics.py +0 -0
  25. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/expansion/_dynamic.py +0 -0
  26. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/expansion/_mapper.py +0 -0
  27. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/expansion/_selection.py +0 -0
  28. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/__init__.py +0 -0
  29. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_bootstrap.py +0 -0
  30. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_col_string.py +0 -0
  31. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_fix_categories.py +0 -0
  32. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_format_time.py +0 -0
  33. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_offloader.py +0 -0
  34. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_output_files.py +0 -0
  35. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_pad.py +0 -0
  36. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_predict_model.py +0 -0
  37. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/helpers/_prepare_data.py +0 -0
  38. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/initialization/__init__.py +0 -0
  39. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/initialization/_censoring.py +0 -0
  40. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/initialization/_denominator.py +0 -0
  41. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/initialization/_numerator.py +0 -0
  42. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/initialization/_outcome.py +0 -0
  43. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/plot/__init__.py +0 -0
  44. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/plot/_survival_plot.py +0 -0
  45. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/weighting/__init__.py +0 -0
  46. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/weighting/_weight_bind.py +0 -0
  47. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/weighting/_weight_data.py +0 -0
  48. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/weighting/_weight_fit.py +0 -0
  49. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/weighting/_weight_offload.py +0 -0
  50. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/weighting/_weight_pred.py +0 -0
  51. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget/weighting/_weight_stats.py +0 -0
  52. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget.egg-info/SOURCES.txt +0 -0
  53. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget.egg-info/dependency_links.txt +0 -0
  54. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget.egg-info/requires.txt +0 -0
  55. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/pySEQTarget.egg-info/top_level.txt +0 -0
  56. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/setup.cfg +0 -0
  57. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_accessor.py +0 -0
  58. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_check_separation.py +0 -0
  59. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_coefficients.py +0 -0
  60. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_covariates.py +0 -0
  61. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_fix_categories.py +0 -0
  62. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_followup_options.py +0 -0
  63. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_hazard.py +0 -0
  64. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_no_variation.py +0 -0
  65. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_offload.py +0 -0
  66. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_parallel.py +0 -0
  67. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_plot.py +0 -0
  68. {pyseqtarget-0.13.0 → pyseqtarget-0.13.2}/tests/test_reproducibility.py +0 -0
  69. {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.0
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) -> None:
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 != "ITT":
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.0
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.0"
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