File: is-set.R

package info (click to toggle)
r-cran-assertive.sets 0.0-3-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 116 kB
  • sloc: sh: 13; makefile: 2
file content (172 lines) | stat: -rw-r--r-- 4,446 bytes parent folder | download
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#' @rdname are_set_equal
#' @export
are_disjoint_sets <- function(x, y, .xname = get_name_in_parent(x), .yname = get_name_in_parent(y))
{
  intersectionxy <- intersect(x, y)
  if(length(intersectionxy) > 0)
  {
    return(
      false(
        gettext(
          "%s and %s have common elements: %s."
        ), 
        .xname, 
        .yname,
        toString(intersectionxy, width = 100)
      )
    )
  }
  TRUE
}

#' @rdname are_set_equal
#' @export
are_intersecting_sets <- function(x, y, .xname = get_name_in_parent(x), .yname = get_name_in_parent(y))
{
  intersectionxy <- intersect(x, y)
  if(length(intersectionxy) == 0)
  {
    return(
      false(
        gettext(
          "%s and %s have no common elements."
        ), 
        .xname, 
        .yname
      )
    )
  }
  TRUE
}


#' Set comparisons
#' 
#' Checks on the contents of two vectors (ignoring the order of the elements).
#' @param x A vector.
#' @param y Another vector.
#' @param strictly Logical.  If \code{TRUE}, \code{x} and \code{y} should not
#' be set equal.
#' @param .xname Not intended to be used directly.
#' @param .yname Not intended to be used directly.
#' @param severity How severe should the consequences of the assertion be?  
#' Either \code{"stop"}, \code{"warning"}, \code{"message"}, or \code{"none"}.
#' @return The \code{is_*} functions return \code{TRUE} or \code{FALSE}.
#' The \code{assert_*} functions throw an error in the event of failure.
#' @seealso \code{\link[base]{sets}}, \code{\link[sets]{set_is_equal}}
#' @examples
#' # Same contents, different order, returns TRUE
#' are_set_equal(1:5, 5:1)
#' 
#' # Different lengths
#' are_set_equal(1:5, 1:6)
#' 
#' # First vector contains values not in second vector
#' are_set_equal(1:5, c(1:4, 4))
#' 
#' # Second vector contains values not in first vector
#' are_set_equal(c(1:4, 4), 1:5)
#' 
#' # Is x a subset of y?
#' is_subset(1:4, 1:5)
#' is_subset(1:5, 1:4)
#' 
#' # Is x a superset of y?
#' is_superset(1:5, 1:4)
#' is_superset(1:4, 1:5)
#' 
#' # The strictly argument checks for a strict sub/superset
#' is_subset(1:5, 1:5, strictly = TRUE)
#' is_superset(1:5, 1:5, strictly = TRUE)
#' 
#' # Do x and y have common elements?
#' are_intersecting_sets(1:4, 3:6)
#' are_disjoint_sets(1:4, 3:6)
#' 
#' # Types are coerced to be the same, as per base::setdiff
#' are_set_equal(1:4, c("4", "3", "2", "1"))
#' 
#' # Errors are thrown in the event of failure
#' assert_are_set_equal(1:5, 5:1)
#' assertive.base::dont_stop(assert_are_set_equal(1:5, 1:6))
#' 
#' assert_is_subset(1:4, 1:5)
#' assertive.base::dont_stop(assert_is_subset(1:5, 1:4))
#' 
#' assert_is_superset(1:5, 1:4)
#' assertive.base::dont_stop(assert_is_superset(1:4, 1:5))
#' 
#' # A common use case: checking that data contains required columns
#' required_cols <- c("Time", "weight", "Diet")
#' assert_is_superset(colnames(ChickWeight), required_cols)
#' @export
are_set_equal <- function(x, y, .xname = get_name_in_parent(x), .yname = get_name_in_parent(y))
{
  x <- unique(x)
  y <- unique(y)
  if(length(x) != length(y))
  {
    return(
      false(
        gettext(
          "%s and %s have different numbers of elements (%d versus %d)."
        ), 
        .xname, 
        .yname,
        length(x),
        length(y)
      )
    )
  }
  if(!(ok <- is_subset(x, y, FALSE, .xname, .yname)))
  {
    return(ok)
  }  
  if(!(ok <- is_subset(y, x, FALSE, .yname, .xname)))
  {
    return(ok)
  }  
  TRUE
}

#' @rdname are_set_equal
#' @export
is_set_equal <- function(x, y, .xname = get_name_in_parent(x), .yname = get_name_in_parent(y))
{
  .Deprecated("are_set_equal")
  are_set_equal(x, y, .xname, .yname)
}

#' @rdname are_set_equal
#' @export
is_subset <- function(x, y, strictly = FALSE, .xname = get_name_in_parent(x), .yname = get_name_in_parent(y))
{
  diffxy <- setdiff(x, y)
  if(length(diffxy) > 0)
  {
    return(
      false(
        ngettext(
          length(diffxy), 
          "The element %s in %s is not in %s.", 
          "The elements %s in %s are not in %s."
        ),
        toString(sQuote(diffxy), width = 100),
        .xname,
        .yname
      )
    )
  } 
  if(strictly && length(setdiff(y, x)) == 0)
  {
    return(false("%s and %s are set equal.", .xname, .yname))
  }  
  TRUE
}

#' @rdname are_set_equal
#' @export
is_superset <- function(x, y, strictly = FALSE, .xname = get_name_in_parent(x), .yname = get_name_in_parent(y))
{
  is_subset(y, x, strictly, .yname, .xname)
}