Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: basetable
Title: Fast and Memory-Efficient Base R Table Manipulation
Version: 1.4.1
Version: 1.4.2
Authors@R:
person("Imad", "El Badisy", email = "elbadisyimad@gmail.com", role = c("aut", "cre"))
Description: A tabular data manipulation, exploration and validation toolkit
Expand Down
12 changes: 12 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# basetable 1.4.2

## Fixes

* `split()` on a non-data-frame `data` argument (the classic
`split(vector, factor)` base R idiom) now dispatches to `base::split()`
instead of erroring. Previously `split()` unconditionally treated its
first argument as a table, so attaching basetable broke
`split(vector, factor)` anywhere in a session, including inside
R Markdown/Quarto's own rendering pipeline, which calls `split()`
unqualified internally.

# basetable 1.4.1

## New features
Expand Down
3 changes: 3 additions & 0 deletions R/split.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
split <- function(data, by, drop = FALSE, keep.by = TRUE) {
if (!is.data.frame(data)) {
return(base::split(x = data, f = by, drop = drop))
}
bt_split_by(data, by = by, drop = drop, keepby = keep.by)
}
64 changes: 17 additions & 47 deletions cran-comments.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
# CRAN submission comments: basetable 1.3.2
# CRAN submission comments: basetable 1.4.2

## Note to CRAN

This upload supersedes the earlier 0.9.0 submission, which was returned with
a manual review (K. Lauseker, 2026-08-21). Since then the package replaced
its 'data.table' and 'stringi' dependencies with a bundled 'C++' engine and
plain-R tables, and renamed a few exports that clashed with other packages,
so it is now at 1.3.2. Its 'Imports' are now only base and recommended
packages. Please review this version in place of 0.9.0.

The 1.3.1 auto-check (2026-08-31) failed the PDF-manual build: the
`transliterate()` help page carried literal Greek and Cyrillic characters
that the reference-manual LaTeX setup cannot typeset. That page is now
pure ASCII (the example builds the sample strings with `intToUtf8()`), and
`R CMD check --as-cran` builds the PDF manual cleanly.

Both points from the 0.9.0 review are addressed:

* Software names in the Description are single-quoted ('C++', 'basetable').
* The vignettes no longer leave `options()` changed. `functions-reference`
and `benchmarking` capture the prior values in their setup chunk and
restore them in a teardown chunk (`options(.old_opts)` /
`options(basetable.threads = .old_threads)`).
Bug-fix release. `split()` unconditionally treated its first argument as a
table, so attaching basetable broke the base R idiom
`split(vector, factor)` for any non-data-frame input. `split()` now checks
`is.data.frame()` and dispatches to `base::split()` when the input is not a
table, matching base R's behavior for vectors while keeping the existing
table-splitting behavior unchanged.

## Test environments

Expand All @@ -31,36 +17,20 @@ Both points from the 0.9.0 review are addressed:

## R CMD check results

0 errors | 0 warnings | 1 note (New submission)

`R CMD check --as-cran` locally reports a second NOTE that is machine-local:
0 errors | 0 warnings | 3 notes

```
checking compilation flags used ... NOTE
Compilation used the following non-portable flag(s):
'-mno-omit-leaf-frame-pointer'
```

This flag comes from the maintainer's personal `~/.R/Makevars`, not from the
package. The package's own `src/Makevars` sets no non-portable flags, so this
NOTE does not appear on the CI builders or on a clean toolchain.

There is also an INFO about installed size (about 7.8 MB, `libs` about
5.7 MB): the package is a single bundled C++ engine with no linked external
library, and this is its compiled object code.
* `Days since last update: 3` -- this is a quick bug-fix resubmission
following a regression found while writing user-facing documentation.
* `checking compilation flags used ... NOTE` (`-mno-omit-leaf-frame-pointer`)
comes from the maintainer's personal `~/.R/Makevars`, not from the
package's own `src/Makevars`, and does not appear on the CI builders.
* `unable to verify current time` is a local sandbox artifact (no network
access to a time server), not related to the package.

## Release summary

First CRAN release. `basetable` depends on no external computation package.
Every operation runs on a native C++ engine bundled with the package:
projection, filtering, ordering, distinct and duplicate detection, grouping,
grouped reducers, all join kinds, row-binding and `subset()` predicate
evaluation are compiled `.Call` kernels, several of them multi-threaded via
`setthreads()`. Results carry a light `basetable` S3 class over an ordinary
data frame, with `print`, `[`, `as.data.frame` and `as.list` methods.

`data.table` and `dplyr` remain in `Suggests` only, as
competitors in the benchmark vignette.
Patch release fixing a `split()` regression; no other functional changes.
See NEWS.md.

## Downstream dependencies

Expand Down
16 changes: 11 additions & 5 deletions man/split.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@
split(data, by, drop = FALSE, keep.by = TRUE)
}
\arguments{
\item{data}{A data frame or data table.}
\item{data}{A data frame or data table, or an atomic vector.}

\item{by}{Character vector of grouping columns.}
\item{by}{For a data frame, a character vector of grouping columns. For an
atomic vector, a factor (or object coercible to one) the same length as
\code{data}, as in \code{base::split()}.}

\item{drop}{Whether to drop empty groups.}

\item{keep.by}{Whether to keep grouping columns in each piece.}
\item{keep.by}{Whether to keep grouping columns in each piece. Ignored
when \code{data} is not a data frame.}
}
\value{
A named list of basetables.
A named list of basetables (data frame input) or a named list of vectors
(atomic vector input, matching \code{base::split()}).
}
\description{
Split a table into pieces by one or more grouping columns.
Split a table into pieces by one or more grouping columns. When \code{data}
is not a data frame, dispatches to \code{base::split()} so the classic
\code{split(vector, factor)} idiom keeps working with basetable attached.
}
9 changes: 9 additions & 0 deletions tests/testthat/test-split.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,12 @@ test_that("split returns a list of table pieces", {
expect_equal(length(out), 3L)
expect_s3_class(out[[1]], "basetable")
})

test_that("split falls back to base::split() for non-data-frame input", {
x <- 1:10
f <- rep(1:2, 5)

expect_equal(split(x, f), base::split(x, f))
expect_equal(split(letters[1:6], rep(c("a", "b"), 3)),
base::split(letters[1:6], rep(c("a", "b"), 3)))
})
Loading