--- title: "B. Advanced usage" author: "Gerold Hepp" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{B. Advanced usage} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` This vignette illustrates some more advanced concepts of the `DTSg` package, namely reference semantics, chaining and piping as well as swallowing and dropping. --- First, let's load the package as well as some data and let's create a `DTSg` object: ```{r} library(DTSg) data(flow) TS <- DTSg$new(flow) TS ``` ## Reference semantics By default, every method manipulating the values of a `DTSg` object creates a deep clone (copy) of it beforehand. This behaviour can be overridden by setting the `clone` argument of the respective method to `FALSE`. Globally, deep cloning can be controlled with the help of the *DTSgClone* option: ```{r} TS$alter("2007-01-01", "2008-12-31") # `TS` was deep cloned before shortening it, hence its end date is still in the # year 2012 TS options(DTSgClone = FALSE) getOption("DTSgClone") # `TS` was modified in place this time, hence its end date is in the year 2008 # now TS$alter("2007-01-01", "2008-12-31") TS ``` As we can see, with cloning set to `FALSE`, the object was altered in place, i.e. no assignment to a new or reassignment to an existing variable was necessary in order to make the changes stick. This is due to the R6 nature of `DTSg` objects. ### Note Using reference semantics can result in undesired behaviour. Merely assigning a variable representing a `DTSg` object to a new variable does not result in a copy of the object. Instead, both variables will reference and access the same data under the hood, i.e. changing one will also affect the other. In case you want a "real" copy of a `DTSg` object, you will have to use the `clone()` method with its `deep` argument set to `TRUE` (for consistency with the `R6` package its default is `FALSE`): ```{r} TSc <- TS$clone(deep = TRUE) # or 'clone(TS, deep = TRUE)' ``` ## Chaining and piping Especially in combination with reference semantics, chaining and piping can be a fast and comfortable way to apply several object manipulations in a row. While chaining only works in combination with the R6 interface, piping is an exclusive feature of the S3 interface. Let's start with chaining: ```{r} TS <- DTSg$ new(flow)$ alter("2007-01-01", "2008-12-31")$ colapply(interpolateLinear)$ aggregate(byYm____, mean) TS ``` For piping, we have to make sure that R 4.1.0 or later is installed in order to have access to R's native pipe operator `|>` (alternatively, the same can be achieved with the forward-pipe operator `%>%` of the `magrittr` package): ```{r} TS <- new("DTSg", flow) |> alter("2007-01-01", "2008-12-31") |> colapply(interpolateLinear) |> aggregate(byYm____, mean) TS ``` ## Swallowing and dropping An extension to reference semantics of existing `DTSg` objects are reference semantics during object creation. This behaviour can be triggered with the help of the `swallow` argument of the `new()` method. When set to `TRUE`, a `data.table` provided through the `values` argument is "swallowed" by the `DTSg` object, i.e. no copy of it is made and all references to it are removed from the global (and only the global) environment upon successful object creation: ```{r} library(data.table) DT <- copy(flow) ls(pattern = "^DT$") TS <- DTSg$new(DT, swallow = TRUE) ls(pattern = "^DT$") ``` The opposite of swallowing is called dropping. This term refers to querying the values of a `DTSg` object as a reference while removing all references to the original `DTSg` object from the global (and again only the global) environment at the same time: ```{r} TS <- DTSg$new(flow) ls(pattern = "^TS$") DT <- TS$values(drop = TRUE) ls(pattern = "^TS$") ``` ## Column access Sometimes need may arise to access a column other than the one currently processed from a function within the `colapply()` method. This can be accomplished in the following way: ```{r} # add a new column recording if a certain value is missing or not before # carrying out a linear interpolation TS <- DTSg$new(flow) TS$summary() TS$ colapply( function(x, ...) is.na(x), resultCols = "missing" )$ colapply(interpolateLinear)$ summary() # undo the linear interpolation (requires additional access to the previously # created column named "missing", which can be carried out with the help of the # `getCol` method or its shortcut, the `[` operator, and the freely chosen `y` # argument) TS$ colapply( function(x, y, ...) ifelse(y, NA, x), y = TS$getCol("missing") # or 'y = TS["missing"]' )$ summary() ``` Please refer to the help pages for further details.