Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 53 additions & 46 deletions src/soundscapy/r_wrapper/_circe_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,34 @@ def extract_bfgs_fit(bfgs_model: ro.ListVector) -> dict[str, Any]:

Parameters
----------
bfgs_model (RS4): Fitted model object from the circe package.
bfgs_model : ro.ListVector
Fitted model object from the circe package.

Returns
-------
dict: Dictionary containing fit statistics.
dict
Dictionary containing fit statistics.

Examples
--------
>>> # doctest: +SKIP
>>> import soundscapy as sspy
>>> from soundscapy.satp import CircModelE
>>> data = sspy.isd.load()
>>> data_paqs = data[PAQ_IDS]
>>> data_paqs = data_paqs.dropna()
>>> data_cor = data_paqs.corr()
>>> n = len(data_paqs)
>>> circ_model = CircModelE.CIRCUMPLEX
>>> circe_res = sspyr.bfgs(
... data_cor=data_cor,
... n=n,
... scales=PAQ_IDS,
... m_val=3,
... equal_ang=circ_model.equal_ang,
... equal_com=circ_model.equal_com,
... )
>>> fit_stats = sspy.r_wrapper.extract_bfgs_fit(circe_res)
>>> # doctest: +SKIP
>>> import soundscapy as sspy
>>> from soundscapy.satp import CircModelE
>>> data = sspy.isd.load()
>>> data_paqs = data[PAQ_IDS]
>>> data_paqs = data_paqs.dropna()
>>> data_cor = data_paqs.corr()
>>> n = len(data_paqs)
>>> circ_model = CircModelE.CIRCUMPLEX
>>> circe_res = sspyr.bfgs(
... data_cor=data_cor,
... n=n,
... scales=PAQ_IDS,
... m_val=3,
... equal_ang=circ_model.equal_ang,
... equal_com=circ_model.equal_com,
... )
>>> fit_stats = sspy.r_wrapper.extract_bfgs_fit(circe_res)

"""
# Session must already be active (bfgs_model was produced by bfgs()), but
Expand Down Expand Up @@ -98,38 +100,43 @@ def bfgs(

Parameters
----------
data_cor (pd.DataFrame): Correlation matrix of the data.
n (int): Number of observations (participants) used to compute the correlation
matrix. Used by CircE_BFGS for chi-square and RMSEA calculations.
scales (list[str], optional): List of scale names. Defaults to PAQ_IDS.
m_val (int, optional): Number of dimensions. Defaults to 3.
equal_ang (bool, optional): Whether to enforce equal angles constraint.
Defaults to True.
equal_com (bool, optional): Whether to enforce equal communalities constraint.
Defaults to True.
data_cor : pd.DataFrame
Correlation matrix of the data.
n : int
Number of observations (participants) used to compute the correlation
matrix. Used by CircE_BFGS for chi-square and RMSEA calculations.
scales : list[str], optional
List of scale names. Defaults to PAQ_IDS.
m_val : int, optional
Number of dimensions. Defaults to 3.
equal_ang : bool, optional
Whether to enforce equal angles constraint. Defaults to True.
equal_com : bool, optional
Whether to enforce equal communalities constraint. Defaults to True.

Returns
-------
RS4: Fitted model object from the circe package.
ro.ListVector
Fitted model object from the circe package.

Examples
--------
>>> import soundscapy as sspy
>>> from soundscapy.satp import CircModelE
>>> data = sspy.isd.load()
>>> data_paqs = data[PAQ_IDS]
>>> data_paqs = data_paqs.dropna()
>>> data_cor = data_paqs.corr()
>>> n = data_paqs.shape[0]
>>> circ_model = CircModelE.CIRCUMPLEX
>>> circe_res = bfgs(
... data_cor=data_cor,
... n=n,
... scales=PAQ_IDS,
... m_val=3,
... equal_ang=circ_model.equal_ang,
... equal_com=circ_model.equal_com,
... )
>>> import soundscapy as sspy
>>> from soundscapy.satp import CircModelE
>>> data = sspy.isd.load()
>>> data_paqs = data[PAQ_IDS]
>>> data_paqs = data_paqs.dropna()
>>> data_cor = data_paqs.corr()
>>> n = data_paqs.shape[0]
>>> circ_model = CircModelE.CIRCUMPLEX
>>> circe_res = bfgs(
... data_cor=data_cor,
... n=n,
... scales=PAQ_IDS,
... m_val=3,
... equal_ang=circ_model.equal_ang,
... equal_com=circ_model.equal_com,
... )

"""
r = get_r_session()
Expand Down
5 changes: 3 additions & 2 deletions src/soundscapy/r_wrapper/_r_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,8 +599,9 @@ def install_r_packages(packages: list[str] | None = None) -> None:
packnames_to_install.remove("CircE")
logger.info("Installed R package 'CircE' from GitHub")

utils.install_packages(StrVector(packnames_to_install))
logger.info("Installed missing R packages: %s", packnames_to_install)
if packnames_to_install:
utils.install_packages(StrVector(packnames_to_install))
logger.info("Installed missing R packages: %s", packnames_to_install)
else:
logger.debug("All required R packages are already installed")

Expand Down
6 changes: 3 additions & 3 deletions src/soundscapy/satp/circe.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ def to_dict(self) -> dict[str, Any]:
if self.polar_angles is not None:
base.update(self.polar_angles.to_dict())
else:
base.update({paq: None for paq in PAQ_IDS})
base.update(dict.fromkeys(PAQ_IDS))
return base


Expand Down Expand Up @@ -469,7 +469,7 @@ def fit_circe(
if len(data) == 0:
msg = (
"No complete cases found: input DataFrame is empty. "
"Check that data contains valid rows with PAQ1-PAQ8 and participant column."
"Check that data contains valid rows with PAQ1-PAQ8 columns."
)
raise ValueError(msg)
validated = SATPSchema.validate(data, lazy=True)
Expand Down Expand Up @@ -523,7 +523,7 @@ def fit_circe(
"rmsea_l": None,
"rmsea_u": None,
"gdiff": None,
**{paq: None for paq in PAQ_IDS},
**dict.fromkeys(PAQ_IDS),
"error": str(e),
}
)
Expand Down