R Usage

Overview

SCG is implemented in Python but can be accessed from R via the reticulate package. This page demonstrates how to load the pre-computed SCG results from the data application and work with them in R. We also show how to fit the model from scratch in R for users who prefer that workflow.

Setup

Note

Replace the path in use_python() with the path to your own Python installation that has scr installed. To find it, run which python or which python3 in your terminal. Please see reticulate for further guidance.

library(reticulate)
library(ggplot2)
library(dplyr)

Attaching package: 'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
use_python("~/.pyenv/versions/3.11.14/bin/python")
np <- import("numpy")

Loading Pre-computed Results

The results from the data application are saved in ../results/ and can be loaded directly in R without re-fitting the model.

SCG Classifications

results <- read.csv("../results/results.csv")
spot_info <- read.csv("../data/spot_info.csv")
gene_names <- read.csv("../data/gene_names.csv")

scgs <- results[results$scg == "True", ]
cat(nrow(scgs), "SCGs identified out of", nrow(results), "edges\n")
143 SCGs identified out of 1275 edges

Correlation Fields

Corr_est <- np$load("../results/Corr_est.npy")
dim(Corr_est)
[1] 4727   51   51

Visualizing Spatially Varying Edges

boundary_colors <- c("T" = "#7651A6", "N" = "#2E7D6E", "I" = "#C4952D")

plot_corr_field <- function(
  Corr_est,
  spot_info,
  g,
  g_prime,
  gene_names = NULL
) {
  field <- Corr_est[, g + 1, g_prime + 1] # convert 0-indexed to 1-indexed

  df <- data.frame(
    x = spot_info$x,
    y = spot_info$y,
    corr = field,
    region = spot_info$region
  )

  vmax <- max(abs(df$corr))

  g_label <- if (!is.null(gene_names)) {
    gene_names$gene[g + 1]
  } else {
    as.character(g)
  }
  g_prime_label <- if (!is.null(gene_names)) {
    gene_names$gene[g_prime + 1]
  } else {
    as.character(g_prime)
  }

  ggplot(df, aes(x = x, y = y, color = corr)) +
    geom_point(size = 2.0) +
    scale_color_gradient2(
      low = "#2166ac",
      mid = "white",
      high = "#d6604d",
      midpoint = 0,
      limits = c(-vmax, vmax),
      name = "Correlation"
    ) +
    coord_equal() +
    ggtitle(paste0(g_label, "—", g_prime_label)) +
    theme_void() +
    theme(
      legend.position = "right",
      plot.title = element_text(hjust = 0.5, size = 11)
    )
}

plot_corr_field(
  Corr_est,
  spot_info,
  g = 2,
  g_prime = 4,
  gene_names = gene_names
)

plot_corr_field(
  Corr_est,
  spot_info,
  g = 39,
  g_prime = 49,
  gene_names = gene_names
)

Fitting the Model from R

Users who wish to fit SCG from scratch in R can do so via reticulate. The workflow mirrors the Python data application exactly.

scr <- import("scr")
torch <- import("torch")

Y_np <- as.matrix(read.csv("../data/Y.csv"))
Y_np <- t(Y_np)

dims <- dim(Y_np)
N <- dims[1]
P <- dims[2]
K <- L <- as.integer(round(2 * log(P)))

init <- scr$scr_init(
  Y = Y_np,
  L = L,
  K = K,
  a_delta = c(2.1, 3.1),
  b_delta = 1.0,
  a0 = 5.0,
  b0 = 0.5,
  nu = 5.0,
  spca_center = TRUE,
  spca_alpha = 0.01,
  spca_ridge_alpha = 0.01,
  device = scr$DEVICE,
  dtype = scr$DTYPE
)

kernel_hypers <- scr$pick_kernel_params(
  init = init,
  S = as.matrix(spot_info[, c("x", "y")])
)
K_np <- scr$rq_kernel(
  as.matrix(spot_info[, c("x", "y")]),
  v2 = 1.0,
  rho = 0.1 * kernel_hypers$rho,
  alpha = kernel_hypers$alpha
)

fit <- scr$cavi(
  torch$as_tensor(Y_np, device = scr$DEVICE, dtype = scr$DTYPE),
  torch$as_tensor(K_np, device = scr$DEVICE, dtype = scr$DTYPE),
  init,
  max_iter = 60L,
  verbose = FALSE
)

results <- scr$classify_edges(fit$params, M = 500L, alpha = 0.1)
Note

When passing data from R to Python via reticulate, NumPy arrays are non-writable by default. This triggers a PyTorch warning during torch$as_tensor that can be safely ignored.

Session Info

sessionInfo()
R version 4.5.2 (2025-10-31)
Platform: aarch64-apple-darwin20
Running under: macOS Tahoe 26.6.2

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.1

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: America/Chicago
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] dplyr_1.2.1            ggplot2_4.0.3          reticulate_1.46.0.9000

loaded via a namespace (and not attached):
 [1] vctrs_0.7.3        cli_3.6.6          knitr_1.51         rlang_1.3.0       
 [5] xfun_0.60          otel_0.2.0         png_0.1-9          generics_0.1.4    
 [9] S7_0.2.2           jsonlite_2.0.0     labeling_0.4.3     glue_1.8.1        
[13] htmltools_0.5.9    scales_1.4.0       rmarkdown_2.31     grid_4.5.2        
[17] tibble_3.3.1       evaluate_1.0.5     fastmap_1.2.0      yaml_2.3.12       
[21] lifecycle_1.0.5    compiler_4.5.2     RColorBrewer_1.1-3 pkgconfig_2.0.3   
[25] htmlwidgets_1.6.4  Rcpp_1.1.2         farver_2.1.2       lattice_0.22-9    
[29] digest_0.6.39      R6_2.6.1           tidyselect_1.2.1   pillar_1.11.1     
[33] magrittr_2.0.5     Matrix_1.7-4       withr_3.0.3        tools_4.5.2       
[37] gtable_0.3.6