Skip to contents

Given:

  • a sub-set function f;

  • an object x with its margin m;

  • and a grouping factor grp;

the idx_by() function takes indices per group grp.
The result of idx_by() can be supplied to the indexing arguments (see squarebrackets_indx_args) to perform grouped subset operations.

Usage

idx_by(x, m, f, grp, parallel = FALSE, mc.cores = 1L)

Arguments

x

the object from which to compute the indices.

m

a single non-negative integer giving the margin for which to compute indices.
For flat indices or for non-dimensional objects, use m = 0L.

f

a subset function to be applied per group on indices.
If m == 0L, indices is here defined as setNames(1:length(x), names(x)).
If m > 0L, indices is here defined as setNames(1:dim(x)[m], dimnames(x)[[m]]).
The function must produce a character or integer vector as output.
For example, to subset the last element per group, specify:
f = last

grp

a factor giving the groups.

parallel, mc.cores

see BY.

Value

A vector of indices.

Examples



# vectors ====
(a <- 1:20)
#>  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
(grp <- factor(rep(letters[1:5], each = 4)))
#>  [1] a a a a b b b b c c c c d d d d e e e e
#> Levels: a b c d e

# get the last element of `a` for each group in `grp`:
s <- list(idx_by(a, 0L, last, grp))
sb_x(cbind(a, grp), s, 1L)
#>       a grp
#> [1,]  4   1
#> [2,]  8   2
#> [3,] 12   3
#> [4,] 16   4
#> [5,] 20   5


# data.frame ====
x <- data.frame(
  a = sample(1:20),
  b = letters[1:20],
  group = factor(rep(letters[1:5], each = 4))
)
print(x)
#>     a b group
#> 1  10 a     a
#> 2  14 b     a
#> 3  11 c     a
#> 4   3 d     a
#> 5   8 e     b
#> 6   1 f     b
#> 7  18 g     b
#> 8   7 h     b
#> 9   2 i     c
#> 10 13 j     c
#> 11  4 k     c
#> 12 17 l     c
#> 13 19 m     d
#> 14 20 n     d
#> 15 12 o     d
#> 16 15 p     d
#> 17  5 q     e
#> 18 16 r     e
#> 19  9 s     e
#> 20  6 t     e
# get the first row for each group in data.frame `x`:
row <- idx_by(x, 1, first, x$group)
sb2_x(x, row, 1L)
#>    a b group
#> 1 10 a     a
#> 2  8 e     b
#> 3  2 i     c
#> 4 19 m     d
#> 5  5 q     e
# get the first row for each group for which a > 10:
x2 <- sb2_x(x, obs = ~ a > 10)
row <- na.omit(idx_by(x2, 1, first, x2$group))
sb2_x(x2, row, 1L)
#>    a b group
#> 1 14 b     a
#> 2 18 g     b
#> 3 13 j     c
#> 4 19 m     d
#> 5 16 r     e