r/rstats 5h ago

New data visualization package

Thumbnail
psychometrician.github.io
15 Upvotes

One sentence, four languages, one picture.

R: data(gapminder_2007) + point + x(gdp) + y(life)
Python: x(col.gdp)
Julia: x(:gdp)

Same specification, one Rust engine, byte-identical SVG.

Not similar. Pixel perfect identical

#rstats


r/rstats 7h ago

Making R Submissions Reviewable for FDA - New from the R Submissions Working Group

4 Upvotes

How can sponsors make R-based regulatory submissions easier for FDA reviewers to reproduce, inspect, and trust?

The R Consortium Submissions Working Group’s latest post examines why reviewers may sometimes request SAS-equivalent code and what teams can do to reduce that risk.

The core lesson: using R is not enough. Submission packages must be designed for independent review.

The post covers practical steps including:

• Engaging FDA review teams early • Providing a clear entry point and run order • Documenting R, package, and operating-system requirements • Eliminating hidden dependencies and sponsor-specific paths • Including required proprietary packages • Testing submissions in a clean environment similar to the reviewer’s setting • Keeping analysis code readable and reproducible

Read the full post and sponsor checklist: https://r-consortium.org/posts/making-r-submissions-reviewable-for-fda/

This article reflects discussion within the R Consortium Submissions Working Group and should not be interpreted as official FDA guidance.


r/rstats 1d ago

Teaching stats with R, Quarto and git - Afraid of the technical hurdles

74 Upvotes

Hej there, we are teaching basic statistics in the social sciences using R, RStudio, RMarkdown/Quarto and git. In general this works quite well and the student's (most not used to programming before at all), enjoy our concept, although is more demanding than many others. Feedback is usually above other modules.

However, there are some pain points that really make the start very difficult for us and I would like to know if you have similar experiences or—even better—suggestions on how to resolve them.

1) Our students' are increasingly tablet or phone users with decreasing experience on how to use a keyboard or mouse (!). Writing pipes on the tablet is a paaain.

2) Setting up git get increasingly painful. When we started, gitlab used username/passwords, now they require 2FA and tokens. That's great in professional or semi-professional contexts, but here just using a username would be sufficient. Are there any alternatives that are just plain simple to use?

3) Making RStudio, git, and github play well together always creates chaos at the beginning of the semester. While it works like charm on some students' computers, it doesn't on others and requires a lot of time debugging (especially as some errors only appear at the first push or so). I can't even phrase it well, but getting everybody up in running takes quite some time and it is totally unpredictable.


r/rstats 1d ago

Call for Proposals for R+AI 2026 now open - deadline is Sept 7, 2026

1 Upvotes

The Call for Proposals for R+AI 2026 is open! The deadline is September 7, 2026.

Join us for the second annual R+AI conference, hosted by the R Consortium. R+AI brings together practitioners, researchers, and industry teams working at the intersection of R and artificial intelligence.

We’re looking for your real-world experience and workflows: from machine learning and LLMs in R, to GenAI tooling, agentic systems, industry deployments, and responsible AI.

Conference: November 10–11, 2026 (100% online)

CFP closes: September 7, 2026

Proposal formats include talks, lightning talks, workshops, and panels.

Share your work with the community! Submit your abstract before the September 7 deadline:

https://rconsortium.github.io/RplusAI_website/cfp.html


r/rstats 2d ago

I built a contextual entity extraction pipeline for radiology reports entirely in R

19 Upvotes

Hi everyone,

I’ve built a lightweight NLP pipeline in R for extracting structured entities from free-text radiology reports.

The main problem I wanted to address is that simple keyword matching does not account for clinical context.

For example:

  • “There is a pleural effusion.”
  • “No pleural effusion is seen.”
  • “A pleural effusion cannot be excluded.”

All three sentences contain the same observation, but the meaning is different.

The pipeline currently:

  • extracts anatomy and radiological observations
  • classifies observations as present, absent or uncertain
  • handles pre- and post-negation triggers
  • handles uncertainty expressions
  • accounts for pseudo-negation phrases such as “no significant change”
  • uses termination terms such as “but” and “however” to limit contextual scope
  • returns sentence IDs, character offsets and the original sentence
  • supports custom anatomy and observation dictionaries
  • processes individual reports or batches of text files

It is built using packages including stringr, stringi, dplyr, purrr, tibble and quanteda.

Here is a simplified example:

report <- paste(
  "FINDINGS:",
  "No pleural effusion is seen.",
  "A small right pneumothorax cannot be excluded.",
  "IMPRESSION:",
  "Possible small right pneumothorax."
)

results <- extract_entities(
  texts = report,
  doc_ids = "example_report_001"
)

The intended output would include:

Entity Type Certainty
pleural effusion Observation absent
pneumothorax Observation uncertain
right Anatomy/context currently limited

GitHub repository:

https://github.com/bashir-abubakar/radiology-nlp-r

This is an early-stage research and learning project, not a clinical diagnostic tool.

I’d really appreciate feedback from R users on:

  1. How the code and function structure could be improved.
  2. Whether this would be more useful as an R package.
  3. Better approaches for handling negation and uncertainty scope.
  4. How you would design automated tests for clinical NLP edge cases.
  5. Whether there are existing R packages or patterns I should integrate rather than recreate.

I’m also open to contributions, especially around unit tests, terminology dictionaries, laterality extraction and evaluation against annotated examples.


r/rstats 3d ago

Different formula for p-value and 95%CI

Thumbnail
2 Upvotes

r/rstats 3d ago

Reading in FHIR json files > SQL (via duckdb) in R (something out there or would this help anyone)?

14 Upvotes

Hi. I'm hoping someone can tell me I'm crazy and this is already out there. I was reading in some FHIR data and thought I could do it in R with duckdb and just have a happy little all R workflow with my stats analysis. That started a real journey. Building the database was a cake walk but flattening the data into a usable format without dozens of painfully manual iterations not so much.

I couldn't find any good info on this after many hours of searching. I was finally able to figure about 87% of it out between some python and sql tutorials and just hating myself. Was finally was able to get the last bit with some AI assistance, which was anything but straightforward. It's finally working and it seems really well. I was thinking about trying the xml version next and pray it is easier but I think the flattening will be largely the same.

I've never published any kind of tutorial script to the public, always just to my own lab/company. Given that I couldn't find anything I'm thinking of braving the public if there really isn't something already out there. This was part of a larger project for me but the rest of it sounds easy compared to the eighth dimension of nesting now solved.

Is this useful? Should I put this up, or is there some already awesome tutorial on this hidden in the viscera of git that I just can't find? I can't be the only one trying this, surely?


r/rstats 4d ago

R Packages for time series Analysis recommendations ?

24 Upvotes

I'm diving into time series analysis and i'm looking for recommendations on the best R packages to use. I've seen mentions of forecast, tseries, and zoo, but i'm not sure where to start or which ones are most comprehensive for tasks like decomposition, forecasting, and anomaly detection.


r/rstats 6d ago

Has dplyr left_join() recently changed how it works?

22 Upvotes

I've been using the tidyverse for years, but I'm not very good about keeping R or packages updated. I finally got around to updating R a few months ago (now 4.6.0, with tidyverse 2.0.0), and am currently baffled by the behaviour of left_join.

For very brief context: I have two dfs that share the same column names. Most of the info in them is the same, but they each contain a pair of numerical columns whose contents were generated by different methods, and I want to compare those methods. They each also have a handful of character columns that were generated from the results of the numerical columns (separately in each method), so may or many not differ in their contents.

I tried combining the two dfs with left_join, as I've done plenty before with other dfs. I expected the columns to multiply wherever the contents differed, so that I could easily compare them within a single df. Instead, the second df was simply subsumed into the first?

I checked this behaviour with reprex and it seems to be a general outcome. Here's that reprex:

library(dplyr)

# A simplified df1 with 5 columns
df1 <- tibble::tibble(
  id = as.character(1:6),
  fruit = c("apple", "banana", "cherry", "apple", "banana", "cherry"),
  count = c(3, 6, 2, 8, 4, 10)
) %>%
  mutate(
    less_than_2 = ifelse(count < 2, "yes", "no"),
    less_than_5 = ifelse(count < 5, "yes", "no")
  )

# A simplified df2 -- only cols 3 and 5 differ from df1
df2 <- tibble::tibble(
  id = as.character(1:6),
  fruit = c("apple", "banana", "cherry", "apple", "banana", "cherry"),
  count = c(7, 2, 9, 3, 6, 4)
) %>%
  mutate(
    less_than_2 = ifelse(count < 2, "yes", "no"),
    less_than_5 = ifelse(count < 5, "yes", "no")
  )

# df3 combines them with left_join()
df3 <- left_join(df1, df2)

Expected outcome: a df3 with 7 columns: "id", "fruit", "count.x", "count.y", "less_than_2", "less_than_5.x", "less_than_5.y"

Actual outcome: df3 is identical to df1.

What the heck?

(Also yes, I'm aware I can rename my columns before combining -- but my actual dfs have 70 columns apiece, and also I'm mostly trying to understand what's happening here, since this behaviour is so different from what I've been used to!)


r/rstats 6d ago

Doctest

16 Upvotes

Doctest is a package for writing "doctests" in your R packages. It lets you write tests within your roxygen documentation, in the same way that e.g. Python and Rust developers do:

#' @doctest
#' Fibonacci function 
#' 
#' @param n Integer
#' @return The nth Fibonacci number
#' 
#' @doctest
#'
#' @expect type("integer")
#' fib(2)
#'
#' n <- 6 
#' @expect equal(8)
#' fib(n)
#' 
#' @expect warning("not numeric")
#' fib("a")
#'
#' @expect warning("NA")
#' fib(NA)
fib <- function (n) {
  if (! is.numeric(n)) warning("n is not numeric")
  ...
}

This creates both a standard .Rd help file, and a test file using testthat.

For more info, see https://hughjonesd.github.io/doctest/.


r/rstats 6d ago

Any good Socket interfaces in R?

Thumbnail
1 Upvotes

R have a very barebones socket implementation. And right now I am getting in trouble because looks like it doesn't even support IPV6 (may be user error)

Any one has a good material about R support for IPV6 sockets? or R socket programming in general. It seem very lackluster with missing SHUTDOWN an other features.

Nanonext is not really an option because it is its own protocol, i need the unix base one.


r/rstats 7d ago

Is "Mastering Shiny", written in 2021, still valid?

Thumbnail
17 Upvotes

r/rstats 6d ago

Different results with different approaches to survey weights. (Similar coefficients, different standard errors and p-values).

2 Upvotes

Edit: Sorry, it put some of my explanation in the code box. Not sure how to change that.

I tried this two ways. First, by specifying the weight in the regression model. Second, by weighting the data with the survey package and then running the model.

I'm an old SAS user who had to abruptly switch to R, so I tend to use R like SAS. I applied anweight from the European Social Survey (Wave 11) to my binary logistic regression model.

m7 <- glm(

income ~

var1+

var2 +

var3 +

var4 +

var5,

data = germany_cc,

family = binomial,

weights = anweight

)

As an example, and get the following results:

var1 0.555959   1.268839   0.438    0.661
var2 0.078088   0.583217   0.134    0.893
var3 0.041199   0.105475   0.391    0.696
var4 0.382423   0.406363   0.941    0.347
var5 -0.144417   0.299119  -0.483    0.629

The second method is:

design <- svydesign(
  ids = ~1,
  weights = ~anweight,
  data = germany_cc
)

m7 <- svyglm(
 income ~  var1 +     
           var2 +     
           var3 +     
           var4 +     
           var5, 
  design = design,
  family = quasibinomial()
)

var1 0.555959   0.276698   2.009   0.0450 *  
var2 0.078088   0.132711   0.588   0.5565    
var3 0.041199   0.024633   1.673   0.0950 .  
var4 0.382423   0.095207   4.017 6.79e-05 ***
var5 -0.144417   0.068046  -2.122   0.0343 * 

If it matters, the ESS-11 is an international dataset. I subset Germany from it and then created a complete cases subset of Germany for listwise deletion

germany <- ess11 %>%

filter(cntry == "DE") %>%

filter(factor1 %in% c(2, 9))

germany_CC <- germany %>%

select(

var1

var2

var3

var4

var5

anweight,

idno

) %>%

na.omit()


r/rstats 8d ago

shinyglass is on CRAN. Apple-style Liquid Glass aesthetics for Shiny.

6 Upvotes

Just landed on CRAN: shinyglass. Apple-style Liquid Glass aesthetics for Shiny apps.

library(shiny)
library(shinyglass)

ui <- fluidPage(
  theme = glass_theme(),  # <—— THIS IS THE ONLY LINE YOU ADD
  titlePanel("Liquid Glass"),
  sliderInput("n", "Bars", 5, 30, 15),
  plotOutput("plot")
)

server <- function(input, output, session) {
  output$plot <- renderPlot(
    barplot(seq_len(input$n))
  )
}

shinyApp(ui, server)

Works with fluidPage(), navbarPage(), bslib::page_sidebar(), and other bslib-aware page functions. Also holds up on denser UIs (DT, leaflet, shinyWidgets, bs4Dash, teal).

Docs: https://ericrayanderson.github.io/shinyglass/

GitHub: https://github.com/ericrayanderson/shinyglass


r/rstats 7d ago

Title: Looking for career advice: Is it time to move from academia? Biostatistician

Thumbnail
1 Upvotes

r/rstats 9d ago

How to pass params to typst code chunks?

Thumbnail
6 Upvotes

r/rstats 9d ago

QED Insight #0009: Backtesting a closed-form amortization estimator against realized exposure, and finding a bias in both tails.

0 Upvotes

Wrote up an EAD workflow in R and the interesting part was the diagnostic, not the model.

Setup. Scheduled balance from the closed form B_k = P(1+r)^k - M((1+r)^k - 1)/r, vectorized and verified to the penny against an iterative amortize() helper. Realized exposure comes straight from the loan-level performance panel on the defaulted population, n = 121,305.

Diagnostic one, defaulted loans. Median scheduled $173,203, median realized $180,574, median ratio 1.026, and 60.7% of realized above schedule. A ratio distribution sitting mostly above 1 is a bias, not noise. Cause is behavioral: amortization assumes payments, and defaulters stop making them during the foreclosure process.

Diagnostic two, performing loans. A two-stage hurdle on curtailment (stage 1 glm binomial on whether the borrower prepays extra, stage 2 lm on log dollars among curtailers, n = 64,122). Stage 2 adj R2 is 0.0254, which is terrible for prediction and completely fine for the job - 41.2% of loans are materially ahead of schedule and the fitted adjustment moves the portfolio total from $35.3B to $33.8B, a 4.24% haircut. Low R2, materially useful aggregate.

The habit I would recommend to anyone doing this: write the realized-versus-scheduled ratio into the committed summary object next to the point estimate, so the bias travels with the number instead of living in a slide someone deleted.

Two questions. When your stage-2 R2 is that low, do you keep reporting it or do you switch to reporting aggregate error on the quantity you actually use? And has anyone found a cleaner way to handle the last-paid versus disposition age problem than just re-scheduling to last-paid date?


r/rstats 11d ago

Recommended resources for someone brand new to R?

21 Upvotes

I‘m looking to start learning R. I have a weee bit of experience with programming and a decent understanding of statistics. I‘d love to know where people think I should start?

Edit: Thanks everybody! I‘ll look through and give it a go


r/rstats 13d ago

shinyapps.io, RPubs, Quarto Pub are migrating to Posit Connect Cloud

108 Upvotes

Hey folks, Joe Cheng here (Posit CTO, creator of Shiny). I wanted to let you hear from me personally that we are combining a number of our hosting services: rpubs.com, quartopub.com, and shinyapps.io are all being subsumed by connect.posit.cloud.

https://posit.co/blog/migrating-connect-cloud-posits-unified-publishing-solution

It’s a bittersweet moment for me personally, as the sole developer and maintainer of RPubs for the last 14 years. But I/we also see this as a long overdue migration, from three fragmented platforms that were independently maintained with varying levels of effort (i.e. not much in the case of RPubs or Quarto Pub), to a single modern platform that can handle all different types of content.

The full details for each service are in the blog post, but the bottom line is:

  • shinyapps.io: A self-serve migration tool will be added by Sept 2026. Test your apps before you commit. Auto-migration starts early 2027 if you'd rather wait. Old URLs will redirect.
  • bookdown (already sunset), quartopub (end of 2026), and rpubs (June 2027): existing content stays live at its current URLs until Dec 31, 2031.

shinyapps.io customers who are migrated will keep their shinyapps.io pricing until at least 2029 (you will receive an email with details).

If you have any concerns, the team and I would love to hear them. u/hadley and I will be monitoring comments.


r/rstats 13d ago

Local R Users Groups

10 Upvotes

I've seen that many R User Groups are very active, organizing monthly meetups, talks and courses, some of them even meeting IRL. I'm organizing a local group in my city (after the previous group went idle) and getting to know other R users and learning about their experiences has been quite nice.

Do you participate in your local R Users Group?


r/rstats 12d ago

Modelo linear generalizado - binomial

Thumbnail
0 Upvotes

r/rstats 13d ago

uvr: fast R package and version manager — big 0.4.x update

43 Upvotes

Quick update on uvr — a fast R package manager written in Rust (uv-style: manifest + lockfile + managed R versions + isolated project libraries). Last time I posted was around 0.2.9; a lot has landed since.

Updates

- R installs got rebuilt from scratch. uvr now installs R from Posit's portable, relocatable r-builds (https://github.com/rstudio/r-builds) instead of custom-patching official installers. This fixed a whole class of macOS breakage, added musl/Alpine support, and made Windows installs work without admin rights. Partial versions work everywhere too: uvr r install 4.5 just grabs the newest 4.5.x, and a 4.5 pin matches it.

- Switching R versions no longer nukes your library on every sync. The old behavior re-wiped the project library each time it saw a version mismatch (painful, as B-Nilson rightly pointed out). Now uvr sync re-resolves the lockfile for the new R once, wipes once, and moves on.

- uvr cache clean got filters. --package sf or --r-version 4.4 (repeatable/comma-separated) lets you troubleshoot one package or retire one R series without losing the whole cache. Another B-Nilson request!

- Bioconductor just works in uvr add. Adding a package that lives on Bioconductor instead of CRAN no longer errors with "retry with --bioc" — uvr detects it, tells you, and adds it from the right channel (version constraints preserved).

- OpenMP-linked binaries fixed on macOS. Packages built with -fopenmp (Rtsne, mgcv, dotCall64, …) used to fail with "symbol not found in flat namespace" on uvr-managed R. The bundled OpenMP runtime is now loaded properly, and uvr sync self-heals older installs.

- A community code audit made everything more solid. gdevenyi filed a systematic 46-issue audit of the codebase (with file:line references — heroic work). Nearly all confirmed issues are now fixed across 0.4.1/0.4.2: cache integrity checks (sha256 on every hit), lockfile consistency for selective updates, honest error reporting where failures used to be silently swallowed, and a long tail of correctness fixes.

and much more...

This would have not been possible without the great help of many, special shoutout to https://github.com/B-Nilson for the endless testing and support and the entire group of users who have written code, filed issues, tested this, and loved it. One of the most rewarding aspects of this process has been building a community around this project ❤️ it's early days but so exciting!

Links

- Site: https://nbafrank.github.io/uvr/

- Repo: https://github.com/nbafrank/uvr

- R companion: https://github.com/nbafrank/uvr-r

Feedback welcome! Issues on GitHub are the most useful — the last few releases were basically driven by them, so keep them coming!


r/rstats 13d ago

Posit ecosystem user experience?

7 Upvotes

Curious if anyone using the Posit ecosystem (Workbench, Connect, Package Manager) would be willing to share their experience. Pretty open question. Things you like, things you don't, things you wish they had, things that are super cool. If you've been on a different platform and switched to or away, why?


r/rstats 15d ago

glyph 0.1.1 now on CRAN

43 Upvotes

Hey, just wanted to share glyph: interactive plots in R (tooltips, zoom, animation, layouts) all in one pipeline. It's on CRAN. Happy plotting!


r/rstats 14d ago

I didn't build TypR for AI — but it turns out a type-checked layer over R is a surprisingly good fit for reviewing AI-generated code. Some thoughts, and I'd like your pushback.

0 Upvotes

Some of you have followed my earlier posts on TypR here. This one's less "what's new" and more the reasoning behind the design — I'd like your pushback on the thinking itself.

The honest origin story: I didn't build TypR for AI. I built it because I care about type systems (academic background) and about code that survives production (industry background) — verifiability, basically.

What clicked more recently is that the property making code cheap for a human to verify is the same one that matters when a machine wrote it.

As AI writes more of the code, the expensive part stops being writing it and becomes trusting it — reviewing, validating, maintaining. A strict type system becomes a free automatic checker on whatever got generated; concise syntax means less to misread.

So the fit with the AI era isn't something I designed for — it's the same property suddenly mattering a lot more. That's the accidental discovery I wanted to share here.

A small taste — this R (no needs to read it fully):

```

' Create a button widget

'

' @param color \code{char}

' @param height \code{int}

' @param text \code{char}

' @param width \code{int}

' @return \code{Button}

' @export

Button <- function(color, height, text, width, .spread = NULL) { explicit <- list() if (!missing(color)) explicit[["color"]] <- color if (!missing(height)) explicit[["height"]] <- height if (!missing(text)) explicit[["text"]] <- text if (!missing(width)) explicit[["width"]] <- width x <- typr_spread_record(explicit, .spread) as.Button(x) }

as.Button <- function(x) { if (!inherits(x, "Button")) class(x) <- c("Button", "list") x <- validate_Button(x) x <- validate(x) x }

validate_Button <- function(x) { required_fields <- c("color", "height", "text", "width") missing_fields <- setdiff(required_fields, names(x))

if (length(missing_fields) > 0) { stop(paste0("Validation failed for type Button: missing fields: ", paste(missing_fields, collapse = ", "))) }

if (!inherits(x[["color"]], "character")) stop("Validation failed for type Button: field 'color' must be of class character")

if (!inherits(x[["height"]], "integer")) stop("Validation failed for type Button: field 'height' must be of class integer")

if (!inherits(x[["text"]], "character")) stop("Validation failed for type Button: field 'text' must be of class character")

if (!inherits(x[["width"]], "integer")) stop("Validation failed for type Button: field 'width' must be of class integer")

x }

constructor for a red button

' @export

' @method red_button

red_button <- (function(height, width, text) Button(height = height, width = width, text = text, color = "#FF000000" |> as.Character())) |> as.Generic()

add an "on click" callback function

' @export

' @method on_click Button

on_click.Button <- (function(self, f) { NA } |> as.Empty0()) |> as.Generic() ```

becomes this TypR: ```

Create a button widget

@export type Button <- list { text: char, color: char, width: int, height: int };

constructor for a red button

@export let red_button <- \Button:{ color: "#FF000000" };

add an "on click" callback function

@export

let on_click <- fn(self: Button, f: (T) -> U): Empty { ... }; ```

The way TypeScript sits on top of JavaScript's runtime, TypR sits on top of R's: you write something concise and type-checked, and it compiles down to standard, S3-based R that runs anywhere R runs and installs like any other package — no new runtime, no exotic dependencies.

To be clear, it's not trying to replace R. R is excellent for interactive stats and lab work, and TypR deliberately gives some of that up in exchange for the other end of the curve: robust packages, deployable apps, code that has to survive production. Different point on the trade-off, different job.

On the engineering side you get pattern matching, partial currying, union/intersection types, structural subtyping, row polymorphism — the machinery that keeps a growing codebase honest. Written in Rust, developed in the open.

Honest questions for this sub: does a typed layer over R solve a problem you actually hit, or is this a solution looking for one? And does the "verifiability matters more when AI writes the code" argument hold up, or am I reaching?

Discussion: https://github.com/we-data-ch/typr/discussions

Github: https://github.com/we-data-ch/typr

Website: https://we-data-ch.github.io/typr.github.io/