Skip to content

Commit 67a3a8e

Browse files
committed
Fixes #1 #25 #38
1 parent 4dc4b1c commit 67a3a8e

31 files changed

Lines changed: 956 additions & 1330 deletions
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Workflow from https://ropensci.org/blog/2026/01/03/r-universe-workflows
2+
name: R-universe check
3+
4+
on:
5+
push:
6+
pull_request:
7+
8+
jobs:
9+
build:
10+
name: R-universe testing
11+
uses: r-universe-org/workflows/.github/workflows/build.yml@v3
12+
with:
13+
universe: ${{ github.repository_owner }}

README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,22 @@ See more details on the state of the tree sequence ecosystem and aims for
1818
`RcppTskit` in [RcppTskit/inst/STATE_and_AIMS.md](RcppTskit/inst/STATE_and_AIMS.md),
1919
including examples on how to use it on its own or to develop new R packages.
2020

21-
TODO: Think how to best point to use cases. Probably best to point to vignette!?
21+
TODO: Think how to best point to use cases. Probably best to point to vignette and pkgdown!?
2222
https://github.com/HighlanderLab/RcppTskit/issues/10
2323

2424
## Status
2525

2626
<!-- badges: start -->
27-
[![R-CMD-check](https://github.com/HighlanderLab/RcppTskit/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/HighlanderLab/RcppTskit/actions/workflows/R-CMD-check.yaml)
2827

29-
[![Codecov test coverage](https://codecov.io/gh/HighlanderLab/RcppTskit/graph/badge.svg)](https://app.codecov.io/gh/HighlanderLab/RcppTskit)
30-
<!-- badges: end -->
28+
[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental) <!-- Row 1, Col 1 --> [![Development](https://img.shields.io/badge/development-active-blue.svg)](https://img.shields.io/badge/development-active-blue.svg) <!-- Row 1, Col 2 --> [![Licence](https://img.shields.io/badge/licence-MIT-blue.svg)](https://opensource.org/licenses/MIT) <!-- Row 1, Col 3 -->
29+
30+
<!-- line break 1 -->
31+
[![CRAN version](https://www.r-pkg.org/badges/version/RcppTskit)](https://CRAN.R-project.org/package=RcppTskit) <!-- Row 2, Col 1 --> ![GitHub version (main)](https://img.shields.io/github/r-package/v/HighlanderLab/RcppTskit/main?filename=RcppTskit%2FDESCRIPTION&label=Github) <!-- Row 2, Col 2 --> [![Downloads - total](https://cranlogs.r-pkg.org/badges/grand-total/RcppTskit)](https://cranlogs.r-pkg.org/badges/grand-total/RcppTskit) <!-- Row 2, Col 3 -->
3132

32-
TODO: Add R package badges (build status, CRAN version, etc.) to README.md #1
33-
https://github.com/HighlanderLab/RcppTskit/issues/1
33+
<!-- line break 2 -->
34+
[![CRAN R CMD check](https://cranchecks.info/badges/summary/RcppTskit)](https://cran.r-project.org/web/checks/check_results_RcppTskit.html) <!-- Row 3, Col 1 --> ![GitHub R CMD check](https://img.shields.io/github/actions/workflow/status/HighlanderLab/RcppTskit/R-CMD-check.yaml?label=GitHub%20R%20CMD%20check) <!-- Row 3, Col 2 --> [![Codecov test coverage](https://codecov.io/gh/HighlanderLab/RcppTskit/graph/badge.svg)](https://app.codecov.io/gh/HighlanderLab/RcppTskit) <!-- Row 3, Col 3 -->
35+
36+
<!-- badges: end -->
3437

3538
## Contents
3639

RcppTskit/DESCRIPTION

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Package: RcppTskit
22
Type: Package
33
Title: R access to the tskit C API
4-
Version: 0.0.1
5-
Date: 2026-01-07
4+
Version: 0.1.0
5+
Date: 2026-01-2607
66
Authors@R:
77
person(given = "Gregor", family = "Gorjanc",
88
email = "gregor.gorjanc@gmail.com",
@@ -21,6 +21,7 @@ Description: Tskit enables performant storage, manipulation, and analysis
2121
and the `reticulate` approach.
2222
URL: https://github.com/highlanderlab/RcppTskit
2323
License: MIT + file LICENSE
24+
Depends: R (>= 4.0.0)
2425
Imports: methods, R6, Rcpp (>= 1.1.0), reticulate
2526
LinkingTo: Rcpp
2627
Suggests: covr, spelling, testthat

RcppTskit/NAMESPACE

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,9 @@
33
export(TreeSequence)
44
export(get_tskit_py)
55
export(kastore_version)
6-
export(ts_dump_ptr)
76
export(ts_load)
8-
export(ts_load_ptr)
9-
export(ts_metadata_length_ptr)
10-
export(ts_num_edges_ptr)
11-
export(ts_num_individuals_ptr)
12-
export(ts_num_migrations_ptr)
13-
export(ts_num_mutations_ptr)
14-
export(ts_num_nodes_ptr)
15-
export(ts_num_populations_ptr)
16-
export(ts_num_provenances_ptr)
17-
export(ts_num_samples_ptr)
18-
export(ts_num_sites_ptr)
19-
export(ts_num_trees_ptr)
20-
export(ts_print_ptr)
217
export(ts_py_to_r)
22-
export(ts_py_to_r_ptr)
23-
export(ts_r_to_py_ptr)
248
export(ts_read)
25-
export(ts_read_ptr)
26-
export(ts_sequence_length_ptr)
27-
export(ts_summary_ptr)
28-
export(ts_time_units_ptr)
29-
export(ts_write_ptr)
309
export(tskit_version)
3110
importFrom(R6,R6Class)
3211
importFrom(Rcpp,cppFunction)

RcppTskit/NEWS.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# RcppTskit news
22

3-
## [0.0.1] - 2025-12-25
3+
All notable changes to RcppTskit are documented in this file.
4+
The file format is based on [Keep a Changelog](https://keepachangelog.com),
5+
and releases adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
46

5-
* Proof of concept with tskit C API version 1.3.0
7+
## [0.1.0] - 2026-01-26
8+
9+
This is the first release.
10+
11+
### Added (new features)
12+
13+
- Initial version of RcppTskit using the tskit C API (version 1.3.0).
14+
- TreeSequence R6 class so R code looks Pythonic.
15+
- `ts_load()` or `TreeSequence$new()` to load a tree sequence from file into R.
16+
- Methods to summarise a tree sequence and its contents `ts$print()`, `ts$num_nodes()`, etc.
17+
- Method to save a tree sequence to a file `ts$dump()`.
18+
- Method to push tree sequence between R and reticulate Python (TODO).
19+
- Most methods have underlying C++ function that work with a pointer to tree sequence object,
20+
for example, `RcppTskit:::ts_load_ptr()`.

RcppTskit/R/Class-TreeSequence.R

Lines changed: 110 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
#' @title Succinct Tree Sequence R6 Class
2-
#' @description An R6 class to hold an external pointer to a tskit tree sequence.
3-
#' As an R6 class, it's functions will look Pythonic and hence resemble the
1+
#' @title Succinct tree sequence R6 Class (TreeSequence)
2+
#' @description An R6 class holding an external pointer to a tree sequence
3+
#' object. As an R6 class, it's methods look Pythonic and hence resemble the
44
#' tskit Python API. Since the class only holds the pointer, it is lightweight.
5-
#' The pointer does not provide direct view for users and currently there is
6-
#' only a limited number of methods available to summarise the tree sequence.
5+
#' Currently there is only a limited number of methods available to summarise
6+
#' the tree sequence.
77
#' @export
88
TreeSequence <- R6Class(
99
classname = "TreeSequence",
@@ -12,10 +12,22 @@ TreeSequence <- R6Class(
1212
pointer = "externalptr",
1313

1414
#' @description Create a \code{\link{TreeSequence}} from a file or a pointer.
15-
#' See \code{\link{ts_load}()} for details and examples.
16-
#' @param file see \code{\link{ts_load}()}
17-
#' @param options see \code{\link{ts_load}()}
18-
#' @param pointer an external pointer to a tree sequence
15+
#' See \code{\link{ts_load}} for details and examples.
16+
#' @param file a string specifying the full path of the tree sequence file.
17+
#' @param options integer bitwise options (see details at
18+
#' \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_treeseq_load}).
19+
#' @param pointer an external pointer to a tree sequence ()
20+
#' @return A \code{\link{TreeSequence}} object.
21+
#' @seealso \code{\link{ts_load}}
22+
#' @examples
23+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
24+
#' ts <- TreeSequence$new(file = ts_file)
25+
#' is(ts)
26+
#' ts
27+
#' ts$num_nodes()
28+
#' # Also
29+
#' ts <- ts_load(ts_file)
30+
#' is(ts)
1931
initialize = function(file, options = 0L, pointer = NULL) {
2032
if (missing(file) && is.null(pointer)) {
2133
stop("Provide a file name or a pointer!")
@@ -43,148 +55,174 @@ TreeSequence <- R6Class(
4355
invisible(self)
4456
},
4557

46-
#' @description Write a tree sequence to a file.
47-
#' See \code{\link{ts_dump}()} for details and examples.
48-
#' @param file see \code{\link{ts_dump}()}
49-
#' @param options see \code{\link{ts_dump}()}
58+
#' @description Write a tree sequence to a file
59+
#' @param file a string specifying the full path of the tree sequence file.
60+
#' @param options integer bitwise options (see details at
61+
#' \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_treeseq_dump}).
62+
#' @return No return value; called for side effects.
63+
#' @examples
64+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
65+
#' ts <- ts_load(ts_file)
66+
#' dump_file <- tempfile()
67+
#' ts$dump(dump_file)
68+
#' ts$write(dump_file) # alias
5069
dump = function(file, options = 0L) {
5170
ts_dump_ptr(self$pointer, file = file, options = options)
5271
},
5372

54-
#' @description Write a tree sequence to a file.
55-
#' Alias for \code{TreeSequence$dump(file, options)}.
56-
#' See \code{\link{ts_dump}()} for details and examples.
57-
#' @param file see \code{\link{ts_dump}()}
58-
#' @param options see \code{\link{ts_dump}()}
73+
#' @description Alias for \code{\link[=TreeSequence]{TreeSequence$dump}}.
74+
#' @param file see
75+
#' @param options see
5976
write = function(file, options = 0L) {
6077
self$dump(file = file, options = options)
6178
},
6279

6380
#' @description Print a summary of a tree sequence and its contents.
64-
#' See \code{\link{ts_print}()} for details and examples.
81+
#' @return list with two data.frames; the first contains tree sequence
82+
#' properties and their value; the second contains the numbers of rows in
83+
#' tables and the length of their metadata.
84+
#' @examples
85+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
86+
#' ts <- ts_load(ts_file)
87+
#' ts$print()
88+
#' ts
6589
print = function() {
6690
cat("Object of class 'TreeSequence'\n")
6791
print(ts_print_ptr(self$pointer))
6892
},
6993

70-
#' @description Summary of properties and number of records in a tree sequence.
71-
#' See \code{\link{ts_summary}()} for details and examples.
72-
summary = function() {
73-
ts_summary_ptr(self$pointer)
94+
#' @description This function saves a tree sequence from R to disk and
95+
#' reads it into reticulate Python for use with \code{tskit} Python API.
96+
#' @param tskit_module reticulate Python module of \code{tskit}. By default,
97+
#' it calls \code{\link{get_tskit_py}} to obtain the module.
98+
#' @param cleanup logical delete the temporary file at the end of the function?
99+
#' @return Tree sequence in reticulate Python.
100+
#' @seealso \code{\link{ts_py_to_r}}, \code{\link{ts_load}}, and
101+
#' \code{\link[=TreeSequence]{TreeSequence$dump}}.
102+
#' @examples
103+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
104+
#' ts_r <- ts_load(ts_file)
105+
#' is(ts_r)
106+
#' ts_r$num_samples() # 160
107+
#'
108+
#' # Transfer the tree sequence to reticulate Python and use tskit Python API
109+
#' ts_py <- ts_r$r_to_py()
110+
#' is(ts_py)
111+
#' ts_py$num_samples # 160
112+
#' ts2_py <- ts_py$simplify(samples = c(0L, 1L, 2L, 3L))
113+
#' ts2_py$num_samples # 4
114+
r_to_py = function(tskit_module = get_tskit_py(), cleanup = TRUE) {
115+
ts_r_to_py_ptr(
116+
self$pointer,
117+
tskit_module = tskit_module,
118+
cleanup = cleanup
119+
)
74120
},
75121

76122
#' @description Get the number of provenances in a tree sequence.
77-
#' See \code{\link{ts_summary}()} for details and examples.
123+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
124+
#' ts <- ts_load(ts_file)
125+
#' ts_num_provenances(ts)
78126
num_provenances = function() {
79127
ts_num_provenances_ptr(self$pointer)
80128
},
81129

82130
#' @description Get the number of populations in a tree sequence.
83-
#' See \code{\link{ts_summary}()} for details and examples.
131+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
132+
#' ts <- ts_load(ts_file)
133+
#' ts_num_populations(ts)
84134
num_populations = function() {
85135
ts_num_populations_ptr(self$pointer)
86136
},
87137

88138
#' @description Get the number of migrations in a tree sequence.
89-
#' See \code{\link{ts_summary}()} for details and examples.
139+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
140+
#' ts <- ts_load(ts_file)
141+
#' ts_num_migrations(ts)
90142
num_migrations = function() {
91143
ts_num_migrations_ptr(self$pointer)
92144
},
93145

94146
#' @description Get the number of individuals in a tree sequence.
95-
#' See \code{\link{ts_summary}()} for details and examples.
147+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
148+
#' ts <- ts_load(ts_file)
149+
#' ts_num_individuals(ts)
96150
num_individuals = function() {
97151
ts_num_individuals_ptr(self$pointer)
98152
},
99153

100154
#' @description Get the number of samples (of nodes) in a tree sequence.
101-
#' See \code{\link{ts_summary}()} for details and examples.
155+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
156+
#' ts <- ts_load(ts_file)
157+
#' ts_num_samples(ts)
102158
num_samples = function() {
103159
ts_num_samples_ptr(self$pointer)
104160
},
105161

106162
#' @description Get the number of nodes in a tree sequence.
107-
#' See \code{\link{ts_summary}()} for details and examples.
163+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
164+
#' ts <- ts_load(ts_file)
165+
#' ts_num_nodes(ts)
108166
num_nodes = function() {
109167
ts_num_nodes_ptr(self$pointer)
110168
},
111169

112170
#' @description Get the number of edges in a tree sequence.
113-
#' See \code{\link{ts_summary}()} for details and examples.
171+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
172+
#' ts <- ts_load(ts_file)
173+
#' ts_num_edges(ts)
114174
num_edges = function() {
115175
ts_num_edges_ptr(self$pointer)
116176
},
117177

118178
#' @description Get the number of trees in a tree sequence.
119-
#' See \code{\link{ts_summary}()} for details and examples.
179+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
180+
#' ts <- ts_load(ts_file)
181+
#' ts_num_trees(ts)
120182
num_trees = function() {
121183
ts_num_trees_ptr(self$pointer)
122184
},
123185

124186
#' @description Get the number of sites in a tree sequence.
125-
#' See \code{\link{ts_summary}()} for details and examples.
187+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
188+
#' ts <- ts_load(ts_file)
189+
#' ts_num_sites(ts)
126190
num_sites = function() {
127191
ts_num_sites_ptr(self$pointer)
128192
},
129193

130194
#' @description Get the number of mutations in a tree sequence.
131-
#' See \code{\link{ts_summary}()} for details and examples.
195+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
196+
#' ts <- ts_load(ts_file)
197+
#' ts_num_mutations(ts)
132198
num_mutations = function() {
133199
ts_num_mutations_ptr(self$pointer)
134200
},
135201

136202
#' @description Get the sequence length.
137-
#' See \code{\link{ts_summary}()} for details and examples.
203+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
204+
#' ts <- ts_load(ts_file)
205+
#' ts_sequence_length(ts)
138206
sequence_length = function() {
139207
ts_sequence_length_ptr(self$pointer)
140208
},
141209

142210
#' @description Get the time units string.
143-
#' See \code{\link{ts_summary}()} for details and examples.
211+
#' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
212+
#' ts <- ts_load(ts_file)
213+
#' ts_time_units(ts)
144214
time_units = function() {
145215
ts_time_units_ptr(self$pointer)
146216
},
147217

148218
#' @description Get the length of metadata in a tree sequence and its tables.
149-
#' See \code{\link{ts_metadata_length}()} for details and examples.
219+
#' @return A named list with the length of metadata.
220+
#' @examples
221+
#'ts_file <- system.file("examples/test.trees", package = "RcppTskit")
222+
#' ts <- ts_load(ts_file)
223+
#'ts$metadata_length()
150224
metadata_length = function() {
151225
ts_metadata_length_ptr(self$pointer)
152-
},
153-
154-
#' @description Transfer a tree sequence from R to reticulate Python.
155-
#' See \code{\link{ts_r_to_py}()} for details and examples.
156-
#' @param tskit_module see \code{\link{ts_r_to_py}()}
157-
#' @param cleanup see \code{\link{ts_r_to_py}()}
158-
r_to_py = function(tskit_module = get_tskit_py(), cleanup = TRUE) {
159-
ts_r_to_py_ptr(
160-
self$pointer,
161-
tskit_module = tskit_module,
162-
cleanup = cleanup
163-
)
164226
}
165227
)
166228
)
167-
168-
#' @name TreeSequence-load-alias
169-
#' @title Create a \code{\link{TreeSequence}} from a file
170-
#' @description
171-
#' Alias for \code{TreeSequence$new(file, options)}
172-
#' See \code{\link{ts_load}()} for details and examples.
173-
#' @param file see \code{\link{ts_load}()}
174-
#' @param options see \code{\link{ts_load}()}
175-
TreeSequence$load <- function(file, options = 0L) {
176-
TreeSequence$new(file = file, options = options)
177-
}
178-
# This one has to be outside of the R6 class definition to work as a generator
179-
180-
#' @name TreeSequence-read-alias
181-
#' @title Create a \code{\link{TreeSequence}} from a file.
182-
#' @description
183-
#' Alias for \code{TreeSequence$new(file, options)}
184-
#' See \code{\link{ts_load}()} for details and examples.
185-
#' @param file see \code{\link{ts_load}()}
186-
#' @param options see \code{\link{ts_load}()}
187-
TreeSequence$read <- function(file, options = 0L) {
188-
TreeSequence$new(file = file, options = options)
189-
}
190-
# This one has to be outside of the R6 class definition to work as a generator

0 commit comments

Comments
 (0)