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
2 changes: 1 addition & 1 deletion .github/workflows/webpages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
with:
r-version: ${{ env.R-VERSION }}
- name: Cache R packages
uses: actions/cache@v2
uses: actions/cache@v4
env:
cache-name: cache-R-packages
with:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ classifiers = [
]
dependencies = [
"pyarrow",
"rpy2 >= 3.5.15"
"rpy2-robjects >= 3.6.2"
]
dynamic = ["version"]

Expand Down
2 changes: 1 addition & 1 deletion rpy2_arrow/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.1.2'
__version__ = '0.1.3'
24 changes: 19 additions & 5 deletions rpy2_arrow/polars.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def ensure_r_polars() -> types.ModuleType:
rpack_polars = rpy2.robjects.packages.importr('polars',
on_conflict='warn')
rpack_polars_version_info = rpack_polars.__version__.split('.')
assert tuple(int(_) for _ in rpack_polars_version_info[:2]) >= (0, 12)
assert tuple(int(_) for _ in rpack_polars_version_info[:2]) >= (1, 0)
return rpack_polars


Expand Down Expand Up @@ -58,7 +58,7 @@ def pypolars_to_rpolars_dataframe(
rpack_polars = ensure_r_polars()
# TODO: There appear to be an odd shortcircuiting that requires toggling
# additional conversion off.
with rpy2.robjects.default_converter.context():
with rpy2arrow.converter.context():
return rpack_polars.as_polars_df(r_arrow_table)


Expand All @@ -69,7 +69,19 @@ def rpolar_to_pypolars_dataframe(
# R polars to R arrow.
rpack_arrow = ensure_r_arrow()
ensure_r_polars()
r_arrow_table = rpack_arrow.as_arrow_table(dataf)
with rpy2.robjects.default_converter.context():
r_arrow_table = rpack_arrow.as_arrow_table(dataf)
return rarrow_to_pypolars_dataframe(r_arrow_table)


def rpolars_env_to_pypolars_dataframe(
dataf: rpy2.rinterface.sexp.SexpEnvironment
) -> polars.DataFrame:
# R polars to R arrow.
rpack_arrow = ensure_r_arrow()
ensure_r_polars()
with rpy2.robjects.default_converter.context():
r_arrow_table = rpack_arrow.as_arrow_table(dataf)
return rarrow_to_pypolars_dataframe(r_arrow_table)


Expand All @@ -92,13 +104,15 @@ def rpolar_to_pypolars_dataframe(

converter._rpy2py_nc_map[rpy2.rinterface.SexpEnvironment].update(
{
'Table': rarrow_to_pypolars_dataframe,
'polars_data_frame': rpolars_env_to_pypolars_dataframe,
'Table': rarrow_to_pypolars_dataframe
}
)

converter._rpy2py_nc_map[rpy2.rinterface.SexpExtPtr].update(
{
'RPolarsDataFrame': rpolar_to_pypolars_dataframe,
# TODO: is this still needed?
'polars_data_frame': rpolar_to_pypolars_dataframe,
}
)

Expand Down
21 changes: 9 additions & 12 deletions rpy2_arrow/tests_polars.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
R_ASVECTOR = rpy2.rinterface.baseenv['as.vector']
R_SQBRACKET = rpy2.rinterface.baseenv['[']
R_LENGTH = rpy2.rinterface.baseenv['length']
R_EQUAL = rpy2.rinterface.baseenv['==']
R_IDENTICAL = rpy2.rinterface.baseenv['identical']


def _cmp_simple(v1, v2):
Expand Down Expand Up @@ -97,7 +97,7 @@ def test_rpolar_to_pypolars_dataframe(self):
([1, 2], polars.Int64, 'Int64', _cmp_simple), # Fails.
([1.1, 2.1], polars.Float32, 'Float32', _cmp_float),
([1.1, 2.1], polars.Float64, 'Float64', _cmp_float),
(['wx', 'yz'], polars.Utf8, 'Utf8', _cmp_simple),
(['wx', 'yz'], polars.Utf8, 'String', _cmp_simple),
(['wx', 'yz', 'wx'], polars.Categorical,
'Categorical', _cmp_simple)
])
Expand All @@ -107,7 +107,7 @@ def test_converter_py2rpy_dataframe(self, values, dtype, rpotype, cmp):
with rpy2polars.converter.context():
globalenv['podataf'] = podataf
r_podataf = globalenv['podataf']
assert tuple(r_podataf.rclass) == ('RPolarsDataFrame',)
assert tuple(r_podataf.rclass) == ('polars_data_frame', 'polars_object')

assert tuple(
R_DOLLAR(r_podataf, 'schema').names
Expand All @@ -116,21 +116,18 @@ def test_converter_py2rpy_dataframe(self, values, dtype, rpotype, cmp):
R_DOLLAR(r_podataf, 'schema'), 1
)[0]
type_in_library = R_DOLLAR(
R_DOLLAR(
getattr(
rpy2polars.rpack_polars, 'pl'
),
'dtypes'
getattr(
rpy2polars.rpack_polars, 'pl'
),
rpotype
)
assert R_EQUAL(
field,
assert R_IDENTICAL(
field.rclass,
# `r-polars` is a bit inconsistent in the way it declares
# types. Some are R functions while others are non-callable
# objects.
type_in_library() if 'function' in type_in_library.rclass
else type_in_library
else type_in_library.rclass
)

@pytest.mark.parametrize(
Expand Down Expand Up @@ -173,6 +170,6 @@ def test_rpl_to_pl(self, rstr, cls):

def test_pl_to_rpl(self):
plobj = polars.DataFrame({'a': [1, 2, 3]})
cls = rpy2.robjects.ExternalPointer
cls = rpy2.robjects.environments.Environment
rplobj = rpy2polars.pl_to_rpl(plobj)
assert isinstance(rplobj, cls)
Loading