Advertisement Β· 728 Γ— 90

Posts by Jem Arnold

Changelog mnirs 0.6.2
CRAN release: 2026-04-18

Changelog mnirs 0.6.2 CRAN release: 2026-04-18

{mnirs} 0.6.2πŸ¦΅πŸ”¦ updated on CRAN with some minor changes:

β€’ ⏱️🌍 improved timestamp parsing and local time zone detection

β€’ πŸ› οΈ Some other small fixes and documentation edits.

`install.packages("mnirs")`

The full changelog is available: πŸ”— jemarnold.github.io/mnirs/news/i...
#rstats #nirs

2 days ago 4 0 0 0

Hmm, raises a good question - what do you think the limiting factor is currently for, I guess improved applications/implementations of mnirs in sport science? πŸ€”

1 week ago 1 0 1 0

Yeah I think the benefit would be the potential for scale. More people exposed to NIRS -> more ideas how to use it 🀞

1 week ago 1 0 1 0

Athletes & coaches already using #NIRS and understanding the opportunities & limitations might have an advantage here when it rolls out? πŸ‘€

1 week ago 1 0 0 0

I don't use "body battery" myself, but I appreciate it's a first step into training load/stress monitoring. "Muscle battery" will likely be similar

More advanced athletes will of course interpret it within greater context gained from experience

1 week ago 1 0 1 0
Preview
Garmin Leaks Trademarks - Two New Products highly Likely Garmin has trademarked Muscle Battery, confirming SmO2 muscle oxygen hardware is coming, and CIRQA, its Whoop competitor. Full analysis of what the filings reveal about both products.

Garmin sounds serious about #muscleoxygenation #mnirs. "Muscle Battery" gives me high hopes and cautious expectations πŸ˜„ What do you think?πŸ€”

Very interested to see how they solve the hardware distribution problem, and how the model learns from repeated measurements

1 week ago 4 0 2 0

Oh that could work. Could point to access with other files already there

1 week ago 1 0 0 0

Good idea, thank

1 week ago 0 0 0 0
Advertisement
Screenshot:

Preview AGENTS.md

# `{mnirs}` Agent Reference

**v0.6.2 | R | MIT** β€” workflow/dependency map. See `README.md` + vignettes for examples.

| | |
|---|---|
| **Author** | Jem Arnold |
| **Website** | https://jemarnold.github.io/mnirs/ |
| **Citation** | \<coming soon\> |

---

## 1. `"mnirs"` β€” data frame/{tibble} subclass

### Metadata

| Attribute | Type | Description |
|---|---|---|
| `nirs_channels` | character vector | NIRS signal column names |
| `time_channel` | character(1) | time column name |
| `event_channel` | character(1) | event/lap column name |
| `nirs_device` | character(1) | device name (auto-detected) |
| `sample_rate` | numeric(1) | Hz |
| `start_timestamp` | POSIXct | absolute start datetime |
| `interval_times` | numeric | set by `extract_intervals()` |
| `interval_span` | numeric(2) | span used in `extract_intervals()` |

`verbose` read from `getOption("mnirs.verbose", TRUE)` or pass explicitly.
Access: `attr(data, "nirs_channels")`.

---

## 2. Pipeline

```
read_mnirs()
  └── resample_mnirs()       # regularise time grid
        └── replace_mnirs()  # clean invalid/outliers/NA
              └── filter_mnirs()  # smooth
                    β”œβ”€β”€ shift_mnirs()    # optional: shift baseline
                    β”œβ”€β”€ rescale_mnirs()  # optional: normalise range
                    └── extract_intervals()
                              └── analyse_kinetics()
                                        └── plot() / print()
```

Screenshot: Preview AGENTS.md # `{mnirs}` Agent Reference **v0.6.2 | R | MIT** β€” workflow/dependency map. See `README.md` + vignettes for examples. | | | |---|---| | **Author** | Jem Arnold | | **Website** | https://jemarnold.github.io/mnirs/ | | **Citation** | \<coming soon\> | --- ## 1. `"mnirs"` β€” data frame/{tibble} subclass ### Metadata | Attribute | Type | Description | |---|---|---| | `nirs_channels` | character vector | NIRS signal column names | | `time_channel` | character(1) | time column name | | `event_channel` | character(1) | event/lap column name | | `nirs_device` | character(1) | device name (auto-detected) | | `sample_rate` | numeric(1) | Hz | | `start_timestamp` | POSIXct | absolute start datetime | | `interval_times` | numeric | set by `extract_intervals()` | | `interval_span` | numeric(2) | span used in `extract_intervals()` | `verbose` read from `getOption("mnirs.verbose", TRUE)` or pass explicitly. Access: `attr(data, "nirs_channels")`. --- ## 2. Pipeline ``` read_mnirs() └── resample_mnirs() # regularise time grid └── replace_mnirs() # clean invalid/outliers/NA └── filter_mnirs() # smooth β”œβ”€β”€ shift_mnirs() # optional: shift baseline β”œβ”€β”€ rescale_mnirs() # optional: normalise range └── extract_intervals() └── analyse_kinetics() └── plot() / print() ```

What is the best way to include an AGENTS.md file for users' bots working with a new #rstats package?

Top level gives a CRAN check note.

Or is {pkgdown} LLMs.txt sufficient? πŸ€”

1 week ago 5 0 2 0

This was from a colleague who had exported .csv from Moxy recordings (where timestamps are properly converted to numeric time values by `mnirs::read_mnirs()`), but then had converted those files to .xlsx for janky manual processing πŸ˜‰ Which we've now streamlined with {mnirs}

1 week ago 0 0 0 0
screenshot of excel spreadsheet and the same spreadsheet read into R. `hh:mm:ss` column in excel shows timestamp values e.g.: "13:52:59", but these are actually fractional numeric values behind the scenes: "0.578". When read by `mnirs::read_mnirs()` this returns an info message declaring "Estimated `sample_rate` = 50000 Hz" which is a few orders of magnitude wrong. Next {mnirs} update will fix this issue!

screenshot of excel spreadsheet and the same spreadsheet read into R. `hh:mm:ss` column in excel shows timestamp values e.g.: "13:52:59", but these are actually fractional numeric values behind the scenes: "0.578". When read by `mnirs::read_mnirs()` this returns an info message declaring "Estimated `sample_rate` = 50000 Hz" which is a few orders of magnitude wrong. Next {mnirs} update will fix this issue!

Just learned about a fun edge case when reading `hh:mm:ss` format from .xlsx, which Excel in its wisdom apparently stores as fractional numeric, resulting in a bit exaggerated sample rate estimates!

Already tested and patched in dev. Should roll out with {mnirs} 0.6.2 by this weekend
#rstats #nirs

1 week ago 6 0 1 0

Next to see if the figures and code chunks will play nice

3 weeks ago 1 0 0 0
Screenshot of manuscript title and subheadings: "mnirs: An R Package for Reading, Processing, and Analysing Muscle Near-Infrared Spectroscopy Data
Jem Arnold
2026-03-31"

Screenshot of manuscript title and subheadings: "mnirs: An R Package for Reading, Processing, and Analysing Muscle Near-Infrared Spectroscopy Data Jem Arnold 2026-03-31"

Really nice #rstats Positron -> Quarto -> .docx workflow this afternoon:

Assist from the chatbots to spell & grammar check, pre-format all my VΜ‡Oβ‚‚s & SmOβ‚‚s, and wrap all my {citations} for endnote. Then render to .docx and let Endnote instantly format the references. Worked once, flawlesslyπŸ‘Œ

3 weeks ago 6 0 1 0

Was certainly an interesting watch, but the obvious AI production makes me hesitate on how far to trust the story πŸ€” Can we get some #rstats community fact checking from those who where there?

3 weeks ago 2 0 1 0

Thanks! Ya I imagine that's true. Similar with the fabled "reviewer 2"

(Although maybe that's more a case of, if I haven't encountered reviewer 2, maybe I'm reviewer 2?" πŸ€”

3 weeks ago 0 0 0 0

Thanks! I think the moral of the story is 'over-prepare, under-deliver' πŸ˜…

3 weeks ago 1 0 0 0

First R package published!

#mnirs #nirs #muscleoxygenation

3 weeks ago 8 0 0 0
Advertisement

Well, thanks for all the good advice #rstats community

Because that was a far smoother first-time CRAN review process than you led me to expect πŸ˜„

6 days from submission to a nice short approval email. I'm as pleased with this as I was having my first academic paper published!

3 weeks ago 14 0 2 0

can't attach here. Check linkedin msg

3 weeks ago 1 0 0 0

To my more rudimentary understanding, Dmax method tends to return the middle of a curve. "The corner of a circle" if you will. Unfortunately that's the least of my concerns here

3 weeks ago 1 0 0 0

I just got around to reading this one. What are your thoughts Hamish?

3 weeks ago 1 0 2 0

Too bad, I wish that did exist with Louis ❀️

I've told my students if I find a confabulated reference, that's basically an instant fail. It's so sloppy to leave that in, how can I trust anything else in the manuscript?

I dunno. Maybe too harsh, and I thankfully haven't had to act on that yet...

4 weeks ago 0 0 0 0

That's funny πŸ₯² There's a lesson here: Think about all of our prompts as telling the chatbot to "behave as if..."

"behave as if you know the answer to this question"

4 weeks ago 2 1 0 2

The fun of adding a new participant dataset and watching {targets} go brrrr

As I learned from others, this is a great tool for reproducible project structure and processing pipeline (it also saves intermediate objects along the way)

books.ropensci.org/targets/
#rstats

4 weeks ago 7 0 0 1
Preview
data-vis-threads/2026-03-20 at main Β· jemarnold/data-vis-threads A repo for sharing data visualisation projects. Contribute to jemarnold/data-vis-threads development by creating an account on GitHub.

Reproduced and updated on request. Now with less wonky VTs (I mean, they're still wonky, but now they're gold-standard wonky)

Data from: Yogev et al., 2023: doi.org/10.3389/fspo...

Methods from: Jamnick et al., 2020: dx.doi.org/10.1007/s402...

Visuals from: πŸ‘‡

1 month ago 1 1 0 1
A raincloud plot showing the distribution of 11 metabolic threshold estimation methods (lactate and ventilatory thresholds) across relative workload (% Wpeak) from two trials each in 21 female and male competitive cyclists. Data from Yogev et al., 2023: https://doi.org/10.3389/fspor.2023.1143393. Thresholds are stacked vertically, colour-coded from red (FatMax; occuring at the lowest intensity) to pink (RER = 1.00, at the highest intensity), each displaying a kernel density curve, individual data points (n β‰ˆ 42), and a white median marker. The intent is to visualise how various threshold estimates return values all along the range of relative intensity, thus suggesting that there is no single true intensity breakpoint, but rather that different methods find threshold-like behaviours at different intensities, depending on which metabolic variable and analyses methods are used.

A raincloud plot showing the distribution of 11 metabolic threshold estimation methods (lactate and ventilatory thresholds) across relative workload (% Wpeak) from two trials each in 21 female and male competitive cyclists. Data from Yogev et al., 2023: https://doi.org/10.3389/fspor.2023.1143393. Thresholds are stacked vertically, colour-coded from red (FatMax; occuring at the lowest intensity) to pink (RER = 1.00, at the highest intensity), each displaying a kernel density curve, individual data points (n β‰ˆ 42), and a white median marker. The intent is to visualise how various threshold estimates return values all along the range of relative intensity, thus suggesting that there is no single true intensity breakpoint, but rather that different methods find threshold-like behaviours at different intensities, depending on which metabolic variable and analyses methods are used.

Pick a threshold, whichever one you want!

Getting a number is cheap. Knowing what the number means and what to do with it is far more valuable

#rstats #dataviz #exphys #sportscience

1 month ago 12 0 1 0
Advertisement
GitHub - jemarnold/mnirs: Muscle Near-Infrared Spectroscopy Data Processing and Analysis Muscle Near-Infrared Spectroscopy Data Processing and Analysis - jemarnold/mnirs

Collecting muscle NIRS data is easy. Knowing what to do with it is harder. I hope this will help to lower the barrier for processing mNIRS data with standardised, reproducible methods.

Download the R package from: github.com/jemarnold/mn...

1 month ago 2 1 0 0
Video

I've just updated {mnirs} 0.5.2 and implemented a Shiny app for a basic no-code workflow

Check it out! Visualise your data quickly and compare effects of different processing methods
jemarnold-mnirs-app.share.connect.posit.cloud

... then tell me when something breaks πŸ˜„ #rstats #mnirs

1 month ago 9 3 1 1

I seem to need to relearn it every time I want to use it properly πŸ˜…

1 month ago 1 0 0 0

Interesting. Thanks. It's occurring with Sonnet 4.6 via copilot via Position assistant. But not so far with VS Claude Code. Can't recall whether it's happened with Opus 4.6. Possibly something about the model access layers?

1 month ago 2 0 1 0