--- title: "Querying a numeric series" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Querying a numeric series} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r setup} library(discretes) ``` Once you have a numeric series, you can materialize it as a numeric vector, check which values are in it, count values in a range, and query limit points (sinks). This vignette covers these query functions. ## Materializing values from a series Materializing a series means producing its discrete values as an ordinary numeric vector. There are three ways to do it. ### Traversing: `next_discrete()` and `prev_discrete()` `next_discrete()` returns the next `n` discrete values in the series starting from a reference point; `prev_discrete()` does the same in the opposite direction. They return a numeric vector of values (of length at most `n`). ```{r} x <- integers() next_discrete(x, from = 10) next_discrete(x, from = 10, n = 5, include_from = TRUE) prev_discrete(x, from = 1.3, n = 5) ``` When `x` is a modified series, traversal is delegated to the underlying series, and the result is mapped back. ### Pulling values: `get_discretes_at()` and `get_discretes_in()` Rather than traversing from a reference point, you can ask for values in a range or at specific values. **`get_discretes_at()`** — Gets specified discrete values from the series, if they can be found in the series (within `tol` of the base series). ```{r} get_discretes_at(integers(), values = c(-10, 4, 3.5, 10, NA)) get_discretes_at(integers(), values = 5.5) ``` **`get_discretes_in()`** — Gets all discrete values within a range. The result is ordered from smallest to largest. If there are infinitely many discrete values in the range, `get_discretes_in()` throws an error; use `num_discretes()` first to check. ```{r} get_discretes_in(integers(), from = 6.6, to = 10.1) get_discretes_in(1 / integers(0, 5)) ``` ### Subsetting by position: `[` When a series has a well-defined first element (e.g. `natural1()`), you can subset by position with `[`. ```{r} natural1()[2] natural1()[c(1, 3, 5)] ``` Unlike `dsct_keep()` and `dsct_drop()`, which return a _new series_, `[` materializes the series as a numeric vector. The behaviour of subsetting is delegated to that of numeric vectors, so you can expect similar behaviour: ```{r} x <- as_discretes(1:4) x[-1] x[c(0, NA, 1, 4, 1, 5)] x[] ``` However, not some functionality available with numeric vectors is not supported for numeric _series_: - Assignment via `[`, like `x[1:3] <- ...` - Subsetting by name, like `x["foo"]` - Subsetting by logical vector, like `x[x < 3]` (futher, comparisons like `x < 3` or `x == 3` do not result in a supported structure). ## Counting: `num_discretes()` `num_discretes()` returns how many discrete values lie in a range. It returns `Inf` for infinite-length series. ```{r} num_discretes(integers(), from = -2, to = 5) num_discretes(1 / 2^integers(), from = 0, to = 1) ``` ## Which values are in the series? Use `has_discretes()` to check whether given values are in the series. It returns a logical vector, one per queried value. ```{r} has_discretes(natural1(), c(0, 1, 2, 2.5)) has_discretes(integers(), c(-10, 0, 10, NA)) ``` `NA` in the queried values yields `NA` in the result. ## Querying sinks A **sink** is a limit point of a numeric series: discrete values get arbitrarily close to it, and there are infinitely many discrete values near the sink. `sinks()` lists all sinks in a matrix of locations and directions: approached from the left (-1) or right (+1). ```{r} sinks(integers()) sinks(0.5^natural0()) reciprocals <- 1 / integers() sinks(reciprocals) ``` `has_sink_in()` or `has_sink_at()` are convenience functions that test for a sink in an interval or at a value. ```{r} has_sink_in(integers()) has_sink_at(integers(), Inf) has_sink_at(integers(), -Inf, dir = "right") ``` For `has_sink_at()`, `dir` can be `"either"` (any direction), `"left"` or `"right"` (sink approached from that side), or `"both"` (approached from both sides). When a series has a sink, there is no “next” or “previous” discrete value on the far side of the sink (e.g. `next_discrete(reciprocals, from = -1)` returns nothing).