Functional forms of special data.table operations.
These functions do not use Non-Standard Evaluation.
These functions also benefit from the security measures that
'squarebrackets' implements for
the pass-by-reference semantics.
dt_aggr()aggregates a data.table or tidytable, applying functions over columns specified incol.dt_setcoe()coercively transforms whole columns of a data.table, using pass-by-reference semantics.dt_setmutate()modifies, adds, or removes columns, possibly based on other existing columns, using pass-by-reference semantics.
Usage
dt_aggr(
x,
row = NULL,
col = NULL,
use = 1:2,
fun,
by,
newnames = NULL,
keyby = FALSE
)
dt_setcoe(
x,
col = NULL,
use = 2L,
v,
chkdup = getOption("squarebrackets.chkdup", FALSE)
)
dt_setmutate(x, mutations)Arguments
- x
a
data.tableortidytable.- row, col, use
see squarebrackets_index_args.
Fordt_setcoe(),usemust be either a scalar positive number to select columns, or a scalar negative number to exclude columns.- fun
an aggregation function, or a list of aggregation functions.
A named list is the preferred form.- by
a character vector, giving the names of the grouping column(s).
- newnames
a vector of names for the aggregated columns.
IfNULL(default),newnameswill be constructed as:paste0(names(fun), "(", names(tt_x(x, 0L, col)), ")").- keyby
Boolean, indicating if the aggregated result should be ordered by the columns specified in
by.- v
the coercive transformation function
- chkdup
- mutations
a named list, or a formula that evaluates to a named list.
List names that correspond to existing columns, will modify those columns.
List names that don't will new create columns with those names.
List contents can beNULLto remove a column, or a vector to replace the column.
In formula form, columns fromxcan be used as variables.
For example, the following formula will transform the existing column named "column3" using other existing columns, and it will create a new column called "newcolumn" as functions from existing columns:~ list(column3 = column1 / column2, newcolumn = column1 + column2)
Value
For dt_aggr():
The aggregated data.table object.
For the rest of the functions:
Returns: VOID. These functions modify the object by reference.
Do not use assignments like x <- dt_setcoe(x, ...).
Since these functions return void, you'll just get NULL.
Examples
# Aggregate data.table ====
d <- data.table::as.data.table(iris)
dt_setcoe(d, "Sepal.Length", 2L, v = as.integer)
print(d)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> <int> <num> <num> <num> <fctr>
#> 1: 5 3.5 1.4 0.2 setosa
#> 2: 4 3.0 1.4 0.2 setosa
#> 3: 4 3.2 1.3 0.2 setosa
#> 4: 4 3.1 1.5 0.2 setosa
#> 5: 5 3.6 1.4 0.2 setosa
#> ---
#> 146: 6 3.0 5.2 2.3 virginica
#> 147: 6 2.5 5.0 1.9 virginica
#> 148: 6 3.0 5.2 2.0 virginica
#> 149: 6 3.4 5.4 2.3 virginica
#> 150: 5 3.0 5.1 1.8 virginica
fun <- rep(list(mean = mean, var = var), 2L)
cols <- rep(c("Sepal.Length", "Sepal.Width"), each = 2L)
dt_aggr(d, 1:5, cols, c(-1, 2), fun = fun, by = "Species")
#> Species mean(Sepal.Length) var(Sepal.Length) mean(Sepal.Width)
#> <fctr> <num> <num> <num>
#> 1: setosa 4.622222 0.2404040 3.444444
#> 2: versicolor 5.480000 0.3363265 2.770000
#> 3: virginica 6.080000 0.4424490 2.974000
#> var(Sepal.Width)
#> <num>
#> 1: 0.15116162
#> 2: 0.09846939
#> 3: 0.10400408
# Aggregate sf-data.table ====
if(requireNamespace("sf")) {
x <- sf::st_read(system.file("shape/nc.shp", package = "sf"))
x <- data.table::as.data.table(x)
x$region <- ifelse(x$CNTY_ID <= 2000, 'high', 'low')
d.aggr <- dt_aggr(
x, 0L, "geometry", fun = sf::st_union, by = "region"
)
head(d.aggr)
}
#> Loading required namespace: sf
#> Reading layer `nc' from data source
#> `D:\Programs\R\R-4.6.1\library\sf\shape\nc.shp' using driver `ESRI Shapefile'
#> Simple feature collection with 100 features and 14 fields
#> Geometry type: MULTIPOLYGON
#> Dimension: XY
#> Bounding box: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
#> Geodetic CRS: NAD27
#> region geometry
#> <char> <sfc_MULTIPOLYGON>
#> 1: high MULTIPOLYGON (((-75.78317 3...
#> 2: low MULTIPOLYGON (((-76.46926 3...
#############################################################################
# dt_setcoe ====
obj <- data.table::data.table(a = 1:10, b = letters[1:10], c = 11:20, d = factor(letters[1:10]))
str(obj) # notice that columns "a" and "c" are INTEGER (`int`)
#> Classes 'data.table' and 'data.frame': 10 obs. of 4 variables:
#> $ a: int 1 2 3 4 5 6 7 8 9 10
#> $ b: chr "a" "b" "c" "d" ...
#> $ c: int 11 12 13 14 15 16 17 18 19 20
#> $ d: Factor w/ 10 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10
#> - attr(*, ".internal.selfref")=<pointer: 0x000001c8d4855ef0>
dt_setcoe(obj, is.numeric, v = as.numeric) # integers are now numeric
str(obj) # now those columns are double/numeric
#> Classes 'data.table' and 'data.frame': 10 obs. of 4 variables:
#> $ a: num 1 2 3 4 5 6 7 8 9 10
#> $ b: chr "a" "b" "c" "d" ...
#> $ c: num 11 12 13 14 15 16 17 18 19 20
#> $ d: Factor w/ 10 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10
#> - attr(*, ".internal.selfref")=<pointer: 0x000001c8d4855ef0>
#############################################################################
# dt_setmutate ====
# add new columns based on other columns:
d <- data.table::as.data.table(iris)
mutations <- ~ n(
Ratio.Length = Sepal.Length / Petal.Length,
Ratio.Width = Sepal.Width / Petal.Width
)
dt_setmutate(d, mutations)
d
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species Ratio.Length
#> <num> <num> <num> <num> <fctr> <num>
#> 1: 5.1 3.5 1.4 0.2 setosa 3.642857
#> 2: 4.9 3.0 1.4 0.2 setosa 3.500000
#> 3: 4.7 3.2 1.3 0.2 setosa 3.615385
#> 4: 4.6 3.1 1.5 0.2 setosa 3.066667
#> 5: 5.0 3.6 1.4 0.2 setosa 3.571429
#> ---
#> 146: 6.7 3.0 5.2 2.3 virginica 1.288462
#> 147: 6.3 2.5 5.0 1.9 virginica 1.260000
#> 148: 6.5 3.0 5.2 2.0 virginica 1.250000
#> 149: 6.2 3.4 5.4 2.3 virginica 1.148148
#> 150: 5.9 3.0 5.1 1.8 virginica 1.156863
#> Ratio.Width
#> <num>
#> 1: 17.500000
#> 2: 15.000000
#> 3: 16.000000
#> 4: 15.500000
#> 5: 18.000000
#> ---
#> 146: 1.304348
#> 147: 1.315789
#> 148: 1.500000
#> 149: 1.478261
#> 150: 1.666667
# remove columns:
dt_setmutate(d, n(Ratio.Width = NULL)) # remove Ratio.Width
d
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species Ratio.Length
#> <num> <num> <num> <num> <fctr> <num>
#> 1: 5.1 3.5 1.4 0.2 setosa 3.642857
#> 2: 4.9 3.0 1.4 0.2 setosa 3.500000
#> 3: 4.7 3.2 1.3 0.2 setosa 3.615385
#> 4: 4.6 3.1 1.5 0.2 setosa 3.066667
#> 5: 5.0 3.6 1.4 0.2 setosa 3.571429
#> ---
#> 146: 6.7 3.0 5.2 2.3 virginica 1.288462
#> 147: 6.3 2.5 5.0 1.9 virginica 1.260000
#> 148: 6.5 3.0 5.2 2.0 virginica 1.250000
#> 149: 6.2 3.4 5.4 2.3 virginica 1.148148
#> 150: 5.9 3.0 5.1 1.8 virginica 1.156863
# transform existing columns:
mutations <- ~ n(Sepal.Length = Sepal.Length /100)
dt_setmutate(d, mutations)
d
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species Ratio.Length
#> <num> <num> <num> <num> <fctr> <num>
#> 1: 0.051 3.5 1.4 0.2 setosa 3.642857
#> 2: 0.049 3.0 1.4 0.2 setosa 3.500000
#> 3: 0.047 3.2 1.3 0.2 setosa 3.615385
#> 4: 0.046 3.1 1.5 0.2 setosa 3.066667
#> 5: 0.050 3.6 1.4 0.2 setosa 3.571429
#> ---
#> 146: 0.067 3.0 5.2 2.3 virginica 1.288462
#> 147: 0.063 2.5 5.0 1.9 virginica 1.260000
#> 148: 0.065 3.0 5.2 2.0 virginica 1.250000
#> 149: 0.062 3.4 5.4 2.3 virginica 1.148148
#> 150: 0.059 3.0 5.1 1.8 virginica 1.156863