Stats-LikeR
view release on metacpan or search on metacpan
SvREFCNT_dec((SV*)cols_av);
SvREFCNT_dec((SV*)seen);
RETVAL = newRV_noinc((SV*)out_hv);
}
OUTPUT:
RETVAL
void filter(df, pred)
SV *df
SV *pred
PPCODE:
{
if (!df || !SvROK(df))
croak("filter: first argument must be a HASH or ARRAY reference (a data frame)");
bool is_code = (pred && SvROK(pred) && SvTYPE(SvRV(pred)) == SVt_PVCV);
if (!is_code && (!pred || !SvROK(pred) || SvTYPE(SvRV(pred)) != SVt_PVHV))
croak("filter: second argument must be a CODE ref or a predicate built with col()");
SV *restrict ref = SvRV(df);
SV *restrict result;
if (SvTYPE(ref) == SVt_PVAV) {
// ----- Array of Hashes: keep matching row hashrefs (shared, not copied) -----
}
RETVAL = newRV_noinc((SV*)results);
}
OUTPUT:
RETVAL
PROTOTYPES: ENABLE
void write_table(...)
PPCODE:
{
SV *restrict data_sv = NULL;
SV *restrict file_sv = NULL;
unsigned int arg_idx = 0;
// Mimic the Perl shift logic
if (arg_idx < items && SvROK(ST(arg_idx))) {
int type = SvTYPE(SvRV(ST(arg_idx)));
if (type == SVt_PVHV || type == SVt_PVAV) {
data_sv = ST(arg_idx);
arg_idx++;
OUTPUT:
RETVAL
void shapiro_test(data)
SV *data
PREINIT:
AV *restrict av;
HV *restrict ret_hash;
size_t n_raw, n = 0;
NV *restrict x, w = 0.0, p_val = 0.0, mean = 0.0, ssq = 0.0;
PPCODE:
if (!SvROK(data) || SvTYPE(SvRV(data)) != SVt_PVAV) {
croak("Expected an array reference");
}
av = (AV *)SvRV(data);
n_raw = av_len(av) + 1;
Newx(x, n_raw, NV);
// Extract variables and calculate mean (skipping undefined/NaN values)
OUTPUT:
RETVAL
void mode(...)
PROTOTYPE: @
PREINIT:
HV *restrict counts;
HV *restrict originals;
size_t max_count = 0, arg_count = 0;
HE *restrict he;
PPCODE:
/* counts: string(value) -> occurrence count */
/* originals: string(value) -> SV* first-seen original */
counts = (HV *)sv_2mortal((SV *)newHV());
originals = (HV *)sv_2mortal((SV *)newHV());
for (size_t i = 0; i < items; i++) {
SV *restrict arg = ST(i);
if (SvROK(arg) && SvTYPE(SvRV(arg)) == SVt_PVAV) {
AV *restrict av = (AV *)SvRV(arg);
size_t len = av_len(av) + 1;
Newx(arr, n, PVal);
Newx(adj, n, NV);
for (size_t i = 0; i < n; i++) {
SV**restrict tv = av_fetch(p_av, i, 0);
arr[i].p = (tv && SvOK(*tv)) ? SvNV(*tv) : 1.0;
arr[i].orig_idx = i;
}
// Sort ascending (Stable sort using original index)
qsort(arr, n, sizeof(PVal), cmp_pval);
PPCODE:
if (strcmp(meth, "bonferroni") == 0) {
for (size_t i = 0; i < n; i++) {
NV v = arr[i].p * n;
adj[arr[i].orig_idx] = (v < 1.0) ? v : 1.0;
}
} else if (strcmp(meth, "holm") == 0) {
NV cummax = 0.0;
for (size_t i = 0; i < n; i++) {
NV v = arr[i].p * (n - i);
if (v > cummax) cummax = v;
for (size_t j = 0; j < ncols_y; j++) Safefree(col_y[j]);
Safefree(col_y);
}
RETVAL = newRV_noinc((SV*)result_av);
}
OUTPUT:
RETVAL
void scale(...)
PROTOTYPE: @
PPCODE:
{
bool do_center_mean = TRUE, do_scale_sd = TRUE;
NV center_val = 0.0, scale_val = 1.0;
size_t data_items = items;
// 1. Parse Options Hash (if it exists as the last argument)
if (items > 0) {
SV*restrict last_arg = ST(items - 1);
if (SvROK(last_arg) && SvTYPE(SvRV(last_arg)) == SVt_PVHV) {
data_items = items - 1; // Exclude hash from data processing
HV*restrict opt_hv = (HV*)SvRV(last_arg);
RETVAL = newRV_noinc((SV*)res_hv);
}
OUTPUT:
RETVAL
void seq(from, to, by = 1.0)
NV from
NV to
NV by
PPCODE:
{
//Handle the zero 'by' case
if (by == 0.0) {
if (from == to) {
EXTEND(SP, 1);
mPUSHn(from);
XSRETURN(1);
} else {
croak("invalid 'by' argument: cannot be zero when from != to");
}
( run in 0.441 second using v1.01-cache-2.11-cpan-5511b514fd6 )