rplatypus Brings PyTorch Medical Imaging Workflows to R

Nov 03, 2026 683 views

Medical imaging teams working in R can now run deep learning workflows through rplatypus, a rebuilt package that combines an R interface with a Python engine based on PyTorch. Its design addresses a long-standing gap in R’s medical imaging tools: image reading and analysis are well supported, but few packages connect those workflows to modern deep learning models.

The package has been submitted to CRAN and is awaiting review. Until it’s available there, it can be installed from GitHub:

# install.packages("remotes")
remotes::install_github("maju116/rplatypus")

A new architecture for a familiar package

rplatypus grew out of platypus, an R package first described in 2020 that offered YOLOv3 object detection and U-Net segmentation through the R keras and tensorflow packages. That version attracted 134 GitHub stars and a backlog of issues, but its dependency chain made maintenance difficult.

The R packages didn’t contain TensorFlow itself. They connected to a Python installation through reticulate, sharing that installation with other software on the user’s machine. A change made for an unrelated project, such as upgrading NumPy, could break platypus. The resulting errors often surfaced outside the package’s own code.

There was another constraint: platypus depended on both the R wrappers and TensorFlow. When TensorFlow changed, the wrappers had to catch up before platypus could move ahead. That left the package waiting on software it couldn’t maintain. The old engine also depended on TensorFlow 2.9, which doesn’t install on Python 3.12.

The rebuild changes both the dependency model and the backend. rplatypus now uses pyplatypus, a Python engine built on PyTorch. The R package calls this engine directly rather than passing through R’s keras and tensorflow layers.

Isolated Python, without a shared environment

Recent changes in reticulate make it possible for packages to declare Python requirements with py_require(). Since version 1.41, reticulate can use uv to create a private, cached environment for those requirements. rplatypus can therefore set up the Python engine it needs without taking over a user’s existing Python installation.

For users, the setup is handled when the engine is first needed; later calls reuse the environment. They don’t have to select an interpreter, activate an environment or match a specific Python version themselves. The package maintainer also controls the engine, rather than waiting for separate R wrappers to support each backend change.

PyTorch is a practical fit for the project’s medical imaging focus. The author points to MONAI, nnU-Net, TorchIO, timm, pretrained encoders and foundation models as examples of the field’s PyTorch ecosystem. Staying with TensorFlow would have meant a rewrite onto a backend the author sees as increasingly out of step with current medical imaging work.

Python engine, R workflow

The split between languages is intentional. Python provides access to model architectures, pretrained weights and medical imaging libraries. The user-facing package keeps tasks such as reading and combining masks, plotting predictions, comparing models and analyzing results in R.

The author considered native R torch, which binds directly to libtorch and does not require Python. For a project maintained by one person in their spare time, that approach would have meant duplicating architectures, losses and data pipelines, while giving up access to pretrained weights in the Python ecosystem.

pyplatypus is also available as a standalone Python package:

pip install "pyplatypus[hub]"

The two packages share a configuration format and are released in sequence. Features are added to the engine first; pyplatypus is then published to PyPI, and rplatypus pins a specific engine version. This gives both languages a common YAML description of an experiment and reduces the chance that an engine change will unexpectedly break an R release.

Making medical image models accessible from R

R already has packages for reading medical images, including RNifti, oro.dicom and divest, alongside a deep learning stack. Yet the author found little connecting those capabilities. A check of the CRAN Task View for Medical Image Analysis, last updated in August 2025, found no deep learning packages listed.

That gap shapes rplatypus’s purpose: users can configure and run medical image models through R while the computation takes place in Python. The initial demonstration uses a published U-Net model trained on the 2018 Data Science Bowl nuclei dataset. The example operates on four microscopy images, each resized to 256 by 256 pixels.

library(rplatypus)
spec <- platypus_spec(
  data = segmentation_data("nuclei", "nuclei", colormap = binary_colormap),
  models = list(u_net(
    "nuclei",
    input_shape = c(256, 256),
    blocks = 4,
    filters = 16,
    weights = "dsbowl-unet",
    fit = FALSE
  ))
)
fit <- platypus_fit(spec, verbose = FALSE)
masks <- predict(fit, split = "validation")
dim(masks)
#> [1] 4 256 256

The output contains one class label per pixel for each image. The example runs on a CPU, without requiring a GPU. platypus_device() reports which device will be used and explains when a GPU can’t be selected.

The published weights produce clean regions on three fluorescence images. On a brightfield image of stained cells, the model finds small dark nuclei instead. The example is meant to show the workflow, not establish performance: these images come from the same collection used to train the weights, so a score on them would give an inflated impression of accuracy.

For measured performance, users can consult the held-out results associated with the published weights. The package’s available_weights() function also describes model limitations. In this case, the U-Net performs semantic segmentation: touching nuclei may merge into a single region, making an object count from the resulting mask unreliable.

One experiment, described in R or YAML

Users can build a model specification with R arguments or store it in a YAML file. For example, this configuration describes the same four-image segmentation setup:

task: semantic_segmentation
data:
  train_path: nuclei
  validation_path: nuclei
  colormap: [[0, 0, 0], [255, 255, 255]]
models:
  - name: nuclei
    architecture: u_net
    input_shape: [256, 256]
    blocks: 4
    filters: 16
    weights: dsbowl-unet
    fit: false

Loading the file with platypus_spec("nuclei.yaml") produces the same specification as the R code. The Python engine can read the very same file with from_yaml(), build the engine and generate predictions. That makes it possible to share an experiment across R and Python users without translating its configuration.

Models and checks in the first release

The current package covers several computer vision tasks. Segmentation includes 2D and 3D U-Net, U-Net++, Res-U-Net and LinkNet models, with eleven loss functions and five metrics that can exclude background pixels. That option matters when the background occupies most of an image and would otherwise dominate a score.

Image classification reports AUC rather than relying on accuracy alone. In an example where only 3% of images contain a finding, a classifier that always predicts “no finding” can reach 0.97 accuracy while failing to identify any positive cases. Object detection uses YOLOv3, with anchors fitted to the dataset’s boxes rather than copied from COCO. Instance segmentation supports object counts, and volume workflows accept NIfTI and DICOM data, account for voxel spacing, split data by patient rather than slice, and report results in millilitres.

The package also aims to expose weak cases instead of hiding them inside a single dataset score: it can report a score for each case, so a poor result can be traced to a specific image. Its validation checks are designed to catch configuration and input problems before a training run, including mismatched colormaps, unexpected channel ordering and missing slices in a DICOM series.

Reference material and seven vignettes, six based on precomputed runs, are available at maju116.github.io/rplatypus. The project’s roadmap includes additional architectures, multi-label classification, ensembling and 3D bounding boxes. The timing and order of that work will depend partly on what users need.

What the rebuild makes possible

The author says the rewrite took about a month, with an AI coding agent, Claude Code, helping with tests, documentation, error messages and coordination between the R package and Python engine. The project’s model choices, datasets, evaluation criteria and published measurements remained the author’s responsibility; reported numbers were measured rather than generated.

That distinction matters because medical imaging software needs results that users can inspect, not just a working prediction call. The package’s emphasis on per-case scores, held-out measurements and explicit model limits gives the workflow a more useful starting point for evaluation. Its next test is whether R users and labs that moved to Python for deep learning find enough value in the shared workflow to bring some of their analysis back to R.

The planned posts will examine that question through specific datasets and failure modes: nuclei segmentation with a mean Dice score of 0.855 that falls to 0.006 on three images; a classifier with 0.97 accuracy that learns nothing useful; YOLOv3 anchor choices and variation across five seeds; CT volume estimates with a Dice score of 0.88 but volumes 12–23% too large; retinal vessels that lose detail when resized; different counts of touching nuclei from the same prediction; and pretrained encoders compared across three imaging modalities.

CRAN’s release schedule may leave its version behind the faster-moving GitHub development branch, so the author expects GitHub to carry the newest version. For teams choosing an R-based medical imaging workflow, the practical question is now whether the Python engine’s model ecosystem and isolated setup can support the analysis they already do in R.

Source: Michał Maj · www.r-bloggers.com

Comments

Sign in to comment.
No comments yet. Be the first to comment.

Related Articles

rplatypus rebuilt: deep learning for medical images in R