File: recycle.R

package info (click to toggle)
r-cran-furrr 0.2.2-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 1,292 kB
  • sloc: sh: 13; makefile: 2
file content (70 lines) | stat: -rw-r--r-- 1,357 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
furrr_recycle_common <- function(x, n) {
  n_x <- length(x)
  lengths <- lengths(x)
  idx <- rep_len(1L, n)

  for (i in seq_len(n_x)) {
    elt <- x[[i]]

    # Don't recycle `NULL` elements, they can be indexed fine by `[` and `[[`
    # and are considered like missing arguments
    if (is.null(elt)) {
      next
    }

    length_elt <- lengths[[i]]

    if (length_elt == n) {
      next
    }

    if (length_elt == 1L) {
      x[[i]] <- elt[idx]
      next
    }

    abort(paste0("Internal error: Incompatible lengths at location ", i, "."))
  }

  x
}

# Can't use `vec_size_common()` because we extract elements with `[[` and
# respect length invariants, not size invariants
furrr_length_common <- function(x) {
  # Don't consider `NULL` elements in common size
  x <- compact_null(x)

  # Handle empty pmap input
  if (length(x) == 0L) {
    return(0L)
  }

  lengths <- lengths(x)
  indices <- seq_along(lengths)

  purrr::reduce2(lengths, indices, furrr_length2, .init = 1L)
}

furrr_length2 <- function(x, y, i) {
  if (x == 1L) {
    y
  } else if (y == 1L) {
    x
  } else if (x == y) {
    x
  } else {
    msg <- paste0("Can't recycle length ", x, " and length ", y, " at location ", i, ".")
    abort(msg)
  }
}

compact_null <- function(x) {
  null <- purrr::map_lgl(x, is.null)

  if (any(null)) {
    x[!null]
  } else {
    x
  }
}