Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php R Laravel Package

kachkaev/php-r

PHP-R is a PHP wrapper for running R code from PHP applications. It lets you evaluate R expressions, pass data between PHP and R, and retrieve results, making statistical computing and R-based analysis accessible from PHP projects.

Deep Wiki
Context7

Getting Started

Install and pin. The package is archived (last release 2017-12-08) and almost certainly declares a PHP 5.5/7.0-era constraint. Install it explicitly and lock it:

composer require kachkaev/php-r
composer show kachkaev/php-r   # note the version + whether Packagist flags it abandoned

If Composer refuses on PHP 8, don't paper over it with --ignore-platform-req in CI — fork the repo into your VCS, bump the constraint, and run the test suite. You want that fork decision made on day one, not the day you upgrade PHP.

Where to look first, in this order:

  1. README.md quickstart — the whole surface is small (vector construction, a handful of element-wise and statistical helpers), so one read is enough to know what exists.
  2. composer.json → autoload — this tells you the real namespace and the entry class. Do not guess it from blog posts; the archived README and autoload map are the only truth.
  3. tests/ — for an abandoned package the tests are the documentation. They pin down recycling behavior, NA handling, and whether statistical helpers take an na.rm-style flag. Read them before you trust a default.

First use case. The one that pays for itself immediately: computing descriptive statistics over a nullable numeric column without hand-rolling loops.

// namespace/class names per the package's composer.json autoload map
$raw = Order::query()->pluck('total')->all();   // [12.5, null, 8.0, 19.99]

// Convert nulls -> the package's NA sentinel exactly once, at the boundary.
$v = R::c(...array_map(fn ($x) => $x ?? NA, $raw));

R::mean($v);          // NA — the missing value propagates
R::mean($v, true);    // 13.5 — na.rm-style flag drops it
R::sd($v, true);

Verify the NA default against the tests before shipping it. The difference between "NA propagates" and "NA silently dropped" is a wrong dashboard number, and it's the single most common way this package bites people.

Implementation Patterns

Wrap it, never call it from domain code. Put the R semantics behind one small interface and bind it in a service provider:

interface VectorStats
{
    public function mean(array $values): ?float;   // null == NA
    public function sd(array $values): ?float;
    public function add(array $a, array $b): array; // recycling lives here
}

The adapter owns three things: null ⇄ NA conversion, the vector construction/destruction, and the na.rm policy. Everything above it speaks plain PHP arrays and ?float. When you eventually replace the archived package (with mathphp, or a hand-rolled 40-liner), you change one class.

Ingest → compute → return scalars/arrays. Long-lived vector objects are the wrong shape for a Laravel app. The reliable flow is pluck() → map nulls → vector → aggregate → plain value. Vectors should not survive past the method that made them: they don't serialize cleanly into cache/session, and there's no hydration story.

Recycling for paired series. This is the genuine reason to prefer the package over Collection::map. R-style recycling aligns a short vector against a longer one, which is exactly what you want for weights, per-group constants, or comparing a baseline against many observations:

// weights recycled across buckets; check length compatibility yourself (see Gotchas)
$weighted = R::multiply($totals, $weights);

NA-aware profiling in an Artisan command. A php artisan data:profile {table} command is the ideal home: it's exploratory, runs off the request path, and prints to the console where a null vs NA distinction is visible rather than swallowed by a JSON response.

Compose in one expression, then break it up. The package's selling point is that mean(sd(x) > 0 ? x : NA) reads like R. Keep those as single expressions inside a method. Don't distribute a vectorized computation across ten statements with intermediate variables — you lose the expressiveness that justified the dependency and gain debugger noise.

Split responsibilities with Collection. Use Laravel collections for shaping, grouping, filtering and joining; hand only the numeric, NA-carrying column to php-r. Reaching for php-r to do groupBy or string work is a net loss.

Pin behavior with characterization tests. Before adopting, write five or six tests that assert your assumptions (mean with NA, sd of a single element, recycling with mismatched lengths, empty vector). They run in milliseconds and they're the regression net the package no longer provides.

Gotchas and Tips

  • Archived means truly unmaintained. No PHP 8 fixes, no security patches, no issues triaged. Treat it as vendored code you own. Fork it, and record the fork point in your README so the next developer isn't confused by the vcs repository entry in composer.json.
  • Index base mismatch. R is 1-based, PHP arrays are 0-based. Any time you map a vector position back to a source array key (or a CSV line number), off-by-one errors appear at the boundaries. Keep the mapping inside the adapter.
  • Recycling hides length bugs. R warns when the shorter operand's length isn't a divisor of the longer one; a PHP port may not. If the lengths are supposed to match, assert(count($a) === count($b)) before the operation. Silent wrong answers are worse than exceptions.
  • NA ≠ null ≠ NAN ≠ INF. Decide on a single conversion helper and use it everywhere. Half-converted data produces aggregates that are either mysteriously NA or mysteriously too low, and both look like a bug in your query.
  • Confirm the na.rm default per function. Read the tests; don't assume consistency across mean, median, sd. Different helpers in small ports often disagree, and the default is what production will use.
  • Float comparisons. NA checks and dedupe logic on doubles need an epsilon; == on computed floats will surprise you. Also expect INF/NAN (not exceptions) from division by zero — validate denominators upstream.
  • Performance ceiling is low. Element-wise operations on PHP objects cost roughly a method call per element. Benchmark at your real row count; past ~100k elements, a SQL AVG/STDDEV or a single pass over plain arrays will be several times faster. This is an exploration tool, not an ETL engine.
  • Memory doubles. You can easily hold the query result, the raw array, and the vector simultaneously. unset() the vector before returning the aggregate in tight loops.
  • Static facade = global state. If the API is static, it's awkward to mock and unsafe to reconfigure per-request. The adapter from "Implementation Patterns" solves this; don't skip it.
  • Debugging. var_dump() on a vector object shows private properties, not your data. Find the package's array-extraction method (or add one in your fork) and log plain arrays instead.
  • No Laravel integration exists. Don't look for a service provider, facade alias, or vendor:publish config — there isn't one. No config quirks to learn, which is also why there's no place to turn off warnings or change NA handling globally.
  • Empty and single-element edge cases. sd of one value and mean of an empty vector are the classic undefined/NA cases. Pin them in tests so a future PHP version can't silently change the answer.
  • Don't try to subclass your way to new features. Compose instead; if you need map, toArray, or a vectorized closure, add it in your fork and send it upstream via your own tag.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums