@@ -202,6 +202,62 @@ TableCollection <- R6Class(
202202 rtsk_table_collection_get_num_nodes(self $ xptr )
203203 },
204204
205+ # ' @description Add a row to the nodes table.
206+ # ' @param flags integer flags for the new node.
207+ # ' @param time numeric time value for the new node.
208+ # ' @param population integer population row ID (0-based, or \code{-1});
209+ # ' \code{NULL} maps to \code{-1}.
210+ # ' @param individual integer individual row ID (0-based, or \code{-1});
211+ # ' \code{NULL} maps to \code{-1}.
212+ # ' @param metadata for the new node; accepts \code{NULL},
213+ # ' a raw vector, or a character of length 1.
214+ # ' @details See the \code{tskit Python} equivalent at
215+ # ' \url{https://tskit.dev/tskit/docs/stable/python-api.html#tskit.NodeTable.add_row}.
216+ # ' The function casts inputs to the expected class. For convenience,
217+ # ' \code{population = NULL} and \code{individual = NULL} are mapped to
218+ # ' \code{-1} (\code{TSK_NULL}).
219+ # ' @return Integer row ID (0-based) of the newly added node.
220+ # ' @examples
221+ # ' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
222+ # ' tc <- tc_load(ts_file)
223+ # ' n_before <- tc$num_nodes()
224+ # ' new_id <- tc$node_table_add_row()
225+ # ' new_id <- tc$node_table_add_row(time = 2.5)
226+ # ' new_id <- tc$node_table_add_row(flags = 1L, time = 3.5, population = 0L)
227+ # ' new_id <- tc$node_table_add_row(flags = 1L, time = 4.5, individual = 0L)
228+ # ' new_id <- tc$node_table_add_row(metadata = "abc")
229+ # ' new_id <- tc$node_table_add_row(metadata = charToRaw("cba"))
230+ # ' n_after <- tc$num_nodes()
231+ node_table_add_row = function (
232+ flags = 0L ,
233+ time = 0 ,
234+ population = - 1L ,
235+ individual = - 1L ,
236+ metadata = NULL
237+ ) {
238+ if (is.null(metadata )) {
239+ metadata_raw <- NULL
240+ } else if (is.raw(metadata )) {
241+ metadata_raw <- metadata
242+ } else if (
243+ is.character(metadata ) && length(metadata ) == 1L && ! is.na(metadata )
244+ ) {
245+ metadata_raw <- charToRaw(metadata )
246+ } else {
247+ stop(
248+ " metadata must be NULL, a raw vector, or a length-1 non-NA character string!"
249+ )
250+ }
251+ rtsk_node_table_add_row(
252+ tc = self $ xptr ,
253+ flags = as.integer(flags ),
254+ time = as.numeric(time ),
255+ population = if (is.null(population )) - 1L else as.integer(population ),
256+ individual = if (is.null(individual )) - 1L else as.integer(individual ),
257+ metadata = metadata_raw
258+ )
259+ },
260+
205261 # ' @description Get the number of edges in a table collection.
206262 # ' @return A signed 64 bit integer \code{bit64::integer64}.
207263 # ' @examples
@@ -212,6 +268,95 @@ TableCollection <- R6Class(
212268 rtsk_table_collection_get_num_edges(self $ xptr )
213269 },
214270
271+ # ' @description Add a row to the edges table.
272+ # ' @param left numeric scalar left coordinate for the new edge.
273+ # ' @param right numeric scalar right coordinate for the new edge.
274+ # ' @param parent integer scalar parent node row ID (0-based).
275+ # ' @param child integer scalar child node row ID (0-based).
276+ # ' @param metadata for the new edge; accepts \code{NULL},
277+ # ' a raw vector, or a character of length 1.
278+ # ' @details See the \code{tskit Python} equivalent at
279+ # ' \url{https://tskit.dev/tskit/docs/stable/python-api.html#tskit.EdgeTable.add_row}.
280+ # ' The function casts inputs to the expected class. Inputs are validated:
281+ # ' \code{left} and \code{right} must be finite numeric scalars with
282+ # ' \code{left < right}, and \code{parent} and \code{child} must be
283+ # ' non-\code{NA} integer scalars.
284+ # ' @return Integer row ID (0-based) of the newly added edge.
285+ # ' @examples
286+ # ' ts_file <- system.file("examples/test.trees", package = "RcppTskit")
287+ # ' tc <- tc_load(ts_file)
288+ # ' parent <- 0L
289+ # ' child <- 1L
290+ # ' n_before <- tc$num_edges()
291+ # ' new_id <- tc$edge_table_add_row(
292+ # ' left = 0, right = 1, parent = parent, child = child
293+ # ' )
294+ # ' new_id <- tc$edge_table_add_row(
295+ # ' left = 1, right = 2, parent = parent, child = child, metadata = "abc"
296+ # ' )
297+ # ' new_id <- tc$edge_table_add_row(
298+ # ' left = 2, right = 3, parent = parent, child = child, metadata = charToRaw("cba")
299+ # ' )
300+ # ' n_after <- tc$num_edges()
301+ edge_table_add_row = function (
302+ left ,
303+ right ,
304+ parent ,
305+ child ,
306+ metadata = NULL
307+ ) {
308+ if (
309+ is.null(left ) ||
310+ length(left ) != 1L ||
311+ ! is.numeric(left ) ||
312+ is.na(left ) ||
313+ ! is.finite(left )
314+ ) {
315+ stop(" left must be a non-NA finite numeric scalar!" )
316+ }
317+ if (
318+ is.null(right ) ||
319+ length(right ) != 1L ||
320+ ! is.numeric(right ) ||
321+ is.na(right ) ||
322+ ! is.finite(right )
323+ ) {
324+ stop(" right must be a non-NA finite numeric scalar!" )
325+ }
326+ if (as.numeric(left ) > = as.numeric(right )) {
327+ stop(" left must be strictly less than right!" )
328+ }
329+ if (
330+ is.null(parent ) || length(parent ) != 1L || is.na(as.integer(parent ))
331+ ) {
332+ stop(" parent must be a non-NA integer scalar!" )
333+ }
334+ if (is.null(child ) || length(child ) != 1L || is.na(as.integer(child ))) {
335+ stop(" child must be a non-NA integer scalar!" )
336+ }
337+ if (is.null(metadata )) {
338+ metadata_raw <- NULL
339+ } else if (is.raw(metadata )) {
340+ metadata_raw <- metadata
341+ } else if (
342+ is.character(metadata ) && length(metadata ) == 1L && ! is.na(metadata )
343+ ) {
344+ metadata_raw <- charToRaw(metadata )
345+ } else {
346+ stop(
347+ " metadata must be NULL, a raw vector, or a length-1 non-NA character string!"
348+ )
349+ }
350+ rtsk_edge_table_add_row(
351+ tc = self $ xptr ,
352+ left = as.numeric(left ),
353+ right = as.numeric(right ),
354+ parent = as.integer(parent ),
355+ child = as.integer(child ),
356+ metadata = metadata_raw
357+ )
358+ },
359+
215360 # ' @description Get the number of sites in a table collection.
216361 # ' @return A signed 64 bit integer \code{bit64::integer64}.
217362 # ' @examples
0 commit comments