| 1 |
# GENERIC METHODS |
|
| 2 | ||
| 3 |
# Data preparation ============================================================= |
|
| 4 |
## Count ----------------------------------------------------------------------- |
|
| 5 |
#' Count Values Using a Predicate |
|
| 6 |
#' |
|
| 7 |
#' Counts values by rows/columns using a predicate function. |
|
| 8 |
#' @param x An \R object (should be a [`matrix`] or a [`data.frame`]). |
|
| 9 |
#' @param f A predicate [`function`]. |
|
| 10 |
#' @param margin A length-one [`numeric`] vector giving the subscripts which the |
|
| 11 |
#' function will be applied over (`1` indicates rows, `2` indicates columns). |
|
| 12 |
#' @param negate A [`logical`] scalar: should the negation of `f` be used |
|
| 13 |
#' instead of `f`? |
|
| 14 |
#' @param na.rm A [`logical`] scalar: should `NA` values be stripped before the |
|
| 15 |
#' computation proceeds? |
|
| 16 |
#' @param ... Further arguments to be passed to `f`. |
|
| 17 |
#' @return A [`numeric`] vector. |
|
| 18 |
#' @example inst/examples/ex-count.R |
|
| 19 |
#' @author N. Frerebeau |
|
| 20 |
#' @docType methods |
|
| 21 |
#' @family data preparation tools |
|
| 22 |
#' @aliases count-method |
|
| 23 |
setGeneric( |
|
| 24 |
name = "count", |
|
| 25 | 78x |
def = function(x, ...) standardGeneric("count")
|
| 26 |
) |
|
| 27 | ||
| 28 |
## Detect ---------------------------------------------------------------------- |
|
| 29 |
#' Find Rows/Columns Using a Predicate |
|
| 30 |
#' |
|
| 31 |
#' Finds rows/columns in an array-like object using a predicate function. |
|
| 32 |
#' @inheritParams count |
|
| 33 |
#' @param all A [`logical`] scalar. If `TRUE`, only the rows/columns whose |
|
| 34 |
#' values all meet the condition defined by `f` are considered. If `FALSE` |
|
| 35 |
#' (the default), only rows/columns where at least one value validates the |
|
| 36 |
#' condition defined by `f` are considered. |
|
| 37 |
#' @param ... Further arguments to be passed to `f`. |
|
| 38 |
#' @return A [`logical`] vector. |
|
| 39 |
#' @example inst/examples/ex-detect.R |
|
| 40 |
#' @author N. Frerebeau |
|
| 41 |
#' @docType methods |
|
| 42 |
#' @family data preparation tools |
|
| 43 |
#' @aliases detect-method |
|
| 44 |
setGeneric( |
|
| 45 |
name = "detect", |
|
| 46 | 59x |
def = function(x, ...) standardGeneric("detect")
|
| 47 |
) |
|
| 48 | ||
| 49 |
## Keep ------------------------------------------------------------------------ |
|
| 50 |
#' Keep Rows/Columns Using a Predicate |
|
| 51 |
#' |
|
| 52 |
#' Keeps rows/columns in an array-like object using a predicate function. |
|
| 53 |
#' @inheritParams detect |
|
| 54 |
#' @param verbose A [`logical`] scalar: should \R report extra information |
|
| 55 |
#' on progress? |
|
| 56 |
#' @example inst/examples/ex-keep.R |
|
| 57 |
#' @author N. Frerebeau |
|
| 58 |
#' @docType methods |
|
| 59 |
#' @family data preparation tools |
|
| 60 |
#' @aliases keep-method |
|
| 61 |
setGeneric( |
|
| 62 |
name = "keep", |
|
| 63 | 10x |
def = function(x, ...) standardGeneric("keep")
|
| 64 |
) |
|
| 65 | ||
| 66 |
#' @rdname keep |
|
| 67 |
#' @aliases keep_columns-method |
|
| 68 |
setGeneric( |
|
| 69 |
name = "keep_columns", |
|
| 70 | 5x |
def = function(x, ...) standardGeneric("keep_columns")
|
| 71 |
) |
|
| 72 | ||
| 73 |
#' @rdname keep |
|
| 74 |
#' @aliases keep_rows-method |
|
| 75 |
setGeneric( |
|
| 76 |
name = "keep_rows", |
|
| 77 | 5x |
def = function(x, ...) standardGeneric("keep_rows")
|
| 78 |
) |
|
| 79 | ||
| 80 |
## Discard --------------------------------------------------------------------- |
|
| 81 |
#' Remove Rows/Columns Using a Predicate |
|
| 82 |
#' |
|
| 83 |
#' Removes rows/columns in an array-like object using a predicate function. |
|
| 84 |
#' @inheritParams detect |
|
| 85 |
#' @param verbose A [`logical`] scalar: should \R report extra information |
|
| 86 |
#' on progress? |
|
| 87 |
#' @example inst/examples/ex-discard.R |
|
| 88 |
#' @author N. Frerebeau |
|
| 89 |
#' @docType methods |
|
| 90 |
#' @family data preparation tools |
|
| 91 |
#' @aliases discard-method |
|
| 92 |
setGeneric( |
|
| 93 |
name = "discard", |
|
| 94 | 39x |
def = function(x, ...) standardGeneric("discard")
|
| 95 |
) |
|
| 96 | ||
| 97 |
#' @rdname discard |
|
| 98 |
#' @aliases discard_columns-method |
|
| 99 |
setGeneric( |
|
| 100 |
name = "discard_columns", |
|
| 101 | 4x |
def = function(x, ...) standardGeneric("discard_columns")
|
| 102 |
) |
|
| 103 | ||
| 104 |
#' @rdname discard |
|
| 105 |
#' @aliases discard_rows-method |
|
| 106 |
setGeneric( |
|
| 107 |
name = "discard_rows", |
|
| 108 | 4x |
def = function(x, ...) standardGeneric("discard_rows")
|
| 109 |
) |
|
| 110 | ||
| 111 |
## Compact --------------------------------------------------------------------- |
|
| 112 |
#' Remove Empty Rows/Columns |
|
| 113 |
#' |
|
| 114 |
#' Removes empty rows/columns in an array-like object. |
|
| 115 |
#' @inheritParams detect |
|
| 116 |
#' @param verbose A [`logical`] scalar: should \R report extra information |
|
| 117 |
#' on progress? |
|
| 118 |
#' @param ... Currently not used. |
|
| 119 |
#' @details |
|
| 120 |
#' A row/column is empty if it contains only zeros (if of type `numeric`) |
|
| 121 |
#' or zero length character strings (if of type `character`). |
|
| 122 |
#' @example inst/examples/ex-compact.R |
|
| 123 |
#' @author N. Frerebeau |
|
| 124 |
#' @docType methods |
|
| 125 |
#' @family data preparation tools |
|
| 126 |
#' @aliases compact-method |
|
| 127 |
setGeneric( |
|
| 128 |
name = "compact", |
|
| 129 | 12x |
def = function(x, ...) standardGeneric("compact")
|
| 130 |
) |
|
| 131 | ||
| 132 |
#' @rdname compact |
|
| 133 |
#' @aliases compact_columns-method |
|
| 134 |
setGeneric( |
|
| 135 |
name = "compact_columns", |
|
| 136 | 5x |
def = function(x, ...) standardGeneric("compact_columns")
|
| 137 |
) |
|
| 138 | ||
| 139 |
#' @rdname compact |
|
| 140 |
#' @aliases compact_rows-method |
|
| 141 |
setGeneric( |
|
| 142 |
name = "compact_rows", |
|
| 143 | 7x |
def = function(x, ...) standardGeneric("compact_rows")
|
| 144 |
) |
|
| 145 | ||
| 146 |
## Seek ------------------------------------------------------------------------ |
|
| 147 |
#' Search Rows/Columns by Name |
|
| 148 |
#' |
|
| 149 |
#' Searches rows/columns by name in an array-like object. |
|
| 150 |
#' @param x An \R object (should be a [`matrix`] or a [`data.frame`]). |
|
| 151 |
#' @param select A [`function`] to be applied to the row/column names |
|
| 152 |
#' (e.g. [startsWith()]) that returns an `integer` or `logical` vector. |
|
| 153 |
#' @param names A [`character`] vector of row/column names to look for. |
|
| 154 |
#' Only used if `select` is `NULL`. |
|
| 155 |
#' @param ... Further arguments to be passed to `select`. |
|
| 156 |
#' @return |
|
| 157 |
#' An [`integer`] vector or `NULL`. |
|
| 158 |
#' @example inst/examples/ex-seek.R |
|
| 159 |
#' @author N. Frerebeau |
|
| 160 |
#' @docType methods |
|
| 161 |
#' @family data preparation tools |
|
| 162 |
#' @name seek |
|
| 163 |
#' @rdname seek |
|
| 164 |
NULL |
|
| 165 | ||
| 166 |
#' @rdname seek |
|
| 167 |
#' @aliases seek_columns-method |
|
| 168 |
setGeneric( |
|
| 169 |
name = "seek_columns", |
|
| 170 | 8x |
def = function(x, ...) standardGeneric("seek_columns")
|
| 171 |
) |
|
| 172 | ||
| 173 |
#' @rdname seek |
|
| 174 |
#' @aliases seek_rows-method |
|
| 175 |
setGeneric( |
|
| 176 |
name = "seek_rows", |
|
| 177 | 8x |
def = function(x, ...) standardGeneric("seek_rows")
|
| 178 |
) |
|
| 179 | ||
| 180 |
## Get ------------------------------------------------------------------------- |
|
| 181 |
#' Get Rows/Columns by Name |
|
| 182 |
#' |
|
| 183 |
#' Returns rows/columns selected by name in an array-like object. |
|
| 184 |
#' @inheritParams seek |
|
| 185 |
#' @return An object of the same sort as `x`. |
|
| 186 |
#' @example inst/examples/ex-seek.R |
|
| 187 |
#' @author N. Frerebeau |
|
| 188 |
#' @docType methods |
|
| 189 |
#' @family data preparation tools |
|
| 190 |
#' @name get |
|
| 191 |
#' @rdname get |
|
| 192 |
NULL |
|
| 193 | ||
| 194 |
#' @rdname get |
|
| 195 |
#' @aliases get_columns-method |
|
| 196 |
setGeneric( |
|
| 197 |
name = "get_columns", |
|
| 198 | 1x |
def = function(x, ...) standardGeneric("get_columns")
|
| 199 |
) |
|
| 200 | ||
| 201 |
#' @rdname get |
|
| 202 |
#' @aliases get_rows-method |
|
| 203 |
setGeneric( |
|
| 204 |
name = "get_rows", |
|
| 205 | 1x |
def = function(x, ...) standardGeneric("get_rows")
|
| 206 |
) |
|
| 207 | ||
| 208 |
## Assign ---------------------------------------------------------------------- |
|
| 209 |
#' Assign a Specific Row/Column to the Column/Row Names |
|
| 210 |
#' |
|
| 211 |
#' @param x A [`data.frame`]. |
|
| 212 |
#' @param row A length-one [`numeric`] vector specifying the row number that is |
|
| 213 |
#' to become the column names. |
|
| 214 |
#' @param column A length-one [`numeric`] vector specifying the column number |
|
| 215 |
#' that is to become the row names. |
|
| 216 |
#' @param remove A [`logical`] scalar: should the specified row/column be removed |
|
| 217 |
#' after making it the column/row names? |
|
| 218 |
#' @param ... Currently not used. |
|
| 219 |
#' @example inst/examples/ex-assign.R |
|
| 220 |
#' @return A [`data.frame`]. |
|
| 221 |
#' @author N. Frerebeau |
|
| 222 |
#' @docType methods |
|
| 223 |
#' @family data preparation tools |
|
| 224 |
#' @name assign |
|
| 225 |
#' @rdname assign |
|
| 226 |
NULL |
|
| 227 | ||
| 228 |
#' @rdname assign |
|
| 229 |
#' @aliases assign_colnames-method |
|
| 230 |
setGeneric( |
|
| 231 |
name = "assign_colnames", |
|
| 232 | 1x |
def = function(x, ...) standardGeneric("assign_colnames")
|
| 233 |
) |
|
| 234 | ||
| 235 |
#' @rdname assign |
|
| 236 |
#' @aliases assign_rownames-method |
|
| 237 |
setGeneric( |
|
| 238 |
name = "assign_rownames", |
|
| 239 | 1x |
def = function(x, ...) standardGeneric("assign_rownames")
|
| 240 |
) |
|
| 241 | ||
| 242 |
## Append ---------------------------------------------------------------------- |
|
| 243 |
#' Convert Row Names to an Explicit Column |
|
| 244 |
#' |
|
| 245 |
#' @param x A [`data.frame`]. |
|
| 246 |
#' @param after A length-one [`numeric`] vector specifying a subscript, |
|
| 247 |
#' after which the row names are to be appended. |
|
| 248 |
#' @param var A [`character`] string giving the name of name of the new column. |
|
| 249 |
#' @param remove A [`logical`] scalar: should the row names be removed? |
|
| 250 |
#' @param ... Currently not used. |
|
| 251 |
#' @example inst/examples/ex-assign.R |
|
| 252 |
#' @return A [`data.frame`]. |
|
| 253 |
#' @author N. Frerebeau |
|
| 254 |
#' @docType methods |
|
| 255 |
#' @family data preparation tools |
|
| 256 |
#' @aliases append_rownames-method |
|
| 257 |
setGeneric( |
|
| 258 |
name = "append_rownames", |
|
| 259 | 1x |
def = function(x, ...) standardGeneric("append_rownames")
|
| 260 |
) |
|
| 261 | ||
| 262 |
#' Add a (Named) Vector as a Column |
|
| 263 |
#' |
|
| 264 |
#' @param x A [`data.frame`]. |
|
| 265 |
#' @param column A (named) `vector`. |
|
| 266 |
#' @param after An [`integer`] specifying a subscript, after which the new |
|
| 267 |
#' column is to be appended. |
|
| 268 |
#' @param var A [`character`] string giving the name of the new column. |
|
| 269 |
#' @param ... Currently not used. |
|
| 270 |
#' @details |
|
| 271 |
#' If `column` is named, names will be matched to the row names of `x`. Only |
|
| 272 |
#' the first match is retained, and elements of `column` without a match are |
|
| 273 |
#' removed. This allows to add as a column a vector whose length is less than |
|
| 274 |
#' the number of rows in `x` (`NA`s will be inserted). |
|
| 275 |
#' @example inst/examples/ex-append.R |
|
| 276 |
#' @return A [`data.frame`]. |
|
| 277 |
#' @author N. Frerebeau |
|
| 278 |
#' @docType methods |
|
| 279 |
#' @family data preparation tools |
|
| 280 |
#' @aliases append_column-method |
|
| 281 |
setGeneric( |
|
| 282 |
name = "append_column", |
|
| 283 | 3x |
def = function(x, ...) standardGeneric("append_column")
|
| 284 |
) |
|
| 285 | ||
| 286 |
# Data cleaning ================================================================ |
|
| 287 |
## NA -------------------------------------------------------------------------- |
|
| 288 |
#' Remove Rows/Columns with Missing Values |
|
| 289 |
#' |
|
| 290 |
#' Removes rows/columns that contain [missing values][NA]. |
|
| 291 |
#' @inheritParams detect |
|
| 292 |
#' @param verbose A [`logical`] scalar: should \R report extra information |
|
| 293 |
#' on progress? |
|
| 294 |
#' @param ... Currently not used. |
|
| 295 |
#' @example inst/examples/ex-missing.R |
|
| 296 |
#' @author N. Frerebeau |
|
| 297 |
#' @docType methods |
|
| 298 |
#' @family data cleaning tools |
|
| 299 |
#' @aliases remove_NA-method |
|
| 300 |
#' @aliases missing |
|
| 301 |
setGeneric( |
|
| 302 |
name = "remove_NA", |
|
| 303 | 4x |
def = function(x, ...) standardGeneric("remove_NA")
|
| 304 |
) |
|
| 305 | ||
| 306 |
#' Replace Missing Values |
|
| 307 |
#' |
|
| 308 |
#' Replaces [missing values][NA] values. |
|
| 309 |
#' @inheritParams detect |
|
| 310 |
#' @param value A possible replacement value. |
|
| 311 |
#' @param ... Currently not used. |
|
| 312 |
#' @example inst/examples/ex-missing.R |
|
| 313 |
#' @author N. Frerebeau |
|
| 314 |
#' @docType methods |
|
| 315 |
#' @family data cleaning tools |
|
| 316 |
#' @aliases replace_NA-method |
|
| 317 |
setGeneric( |
|
| 318 |
name = "replace_NA", |
|
| 319 | 2x |
def = function(x, ...) standardGeneric("replace_NA")
|
| 320 |
) |
|
| 321 | ||
| 322 |
## Inf ------------------------------------------------------------------------- |
|
| 323 |
#' Remove Rows/Columns with Infinite Values |
|
| 324 |
#' |
|
| 325 |
#' Removes rows/columns that contain [infinite values][is.finite]. |
|
| 326 |
#' @inheritParams detect |
|
| 327 |
#' @param verbose A [`logical`] scalar: should \R report extra information |
|
| 328 |
#' on progress? |
|
| 329 |
#' @param ... Currently not used. |
|
| 330 |
#' @example inst/examples/ex-infinite.R |
|
| 331 |
#' @author N. Frerebeau |
|
| 332 |
#' @docType methods |
|
| 333 |
#' @family data cleaning tools |
|
| 334 |
#' @aliases remove_Inf-method |
|
| 335 |
setGeneric( |
|
| 336 |
name = "remove_Inf", |
|
| 337 | 4x |
def = function(x, ...) standardGeneric("remove_Inf")
|
| 338 |
) |
|
| 339 | ||
| 340 |
#' Replace Infinite Values |
|
| 341 |
#' |
|
| 342 |
#' Replaces [infinite values][is.finite] values. |
|
| 343 |
#' @inheritParams detect |
|
| 344 |
#' @param value A possible replacement value. |
|
| 345 |
#' @param ... Currently not used. |
|
| 346 |
#' @example inst/examples/ex-infinite.R |
|
| 347 |
#' @author N. Frerebeau |
|
| 348 |
#' @docType methods |
|
| 349 |
#' @family data cleaning tools |
|
| 350 |
#' @aliases replace_Inf-method |
|
| 351 |
setGeneric( |
|
| 352 |
name = "replace_Inf", |
|
| 353 | 2x |
def = function(x, ...) standardGeneric("replace_Inf")
|
| 354 |
) |
|
| 355 | ||
| 356 |
## Zeros ----------------------------------------------------------------------- |
|
| 357 |
#' Remove Rows/Columns with Zeros |
|
| 358 |
#' |
|
| 359 |
#' Removes rows/columns that contain zeros. |
|
| 360 |
#' @inheritParams detect |
|
| 361 |
#' @param verbose A [`logical`] scalar: should \R report extra information |
|
| 362 |
#' on progress? |
|
| 363 |
#' @param ... Currently not used. |
|
| 364 |
#' @example inst/examples/ex-zero.R |
|
| 365 |
#' @author N. Frerebeau |
|
| 366 |
#' @docType methods |
|
| 367 |
#' @family data cleaning tools |
|
| 368 |
#' @aliases remove_zero-method |
|
| 369 |
#' @aliases zero |
|
| 370 |
setGeneric( |
|
| 371 |
name = "remove_zero", |
|
| 372 | 4x |
def = function(x, ...) standardGeneric("remove_zero")
|
| 373 |
) |
|
| 374 | ||
| 375 |
#' Replace Zeros |
|
| 376 |
#' |
|
| 377 |
#' Replaces zeros. |
|
| 378 |
#' @inheritParams detect |
|
| 379 |
#' @param value A possible replacement value. |
|
| 380 |
#' @param ... Currently not used. |
|
| 381 |
#' @example inst/examples/ex-zero.R |
|
| 382 |
#' @author N. Frerebeau |
|
| 383 |
#' @docType methods |
|
| 384 |
#' @family data cleaning tools |
|
| 385 |
#' @aliases replace_zero-method |
|
| 386 |
setGeneric( |
|
| 387 |
name = "replace_zero", |
|
| 388 | 2x |
def = function(x, ...) standardGeneric("replace_zero")
|
| 389 |
) |
|
| 390 | ||
| 391 |
## Empty string ---------------------------------------------------------------- |
|
| 392 |
#' Remove Rows/Columns with Empty String |
|
| 393 |
#' |
|
| 394 |
#' Removes rows/columns that contain empty strings. |
|
| 395 |
#' @inheritParams detect |
|
| 396 |
#' @param verbose A [`logical`] scalar: should \R report extra information |
|
| 397 |
#' on progress? |
|
| 398 |
#' @param ... Currently not used. |
|
| 399 |
#' @example inst/examples/ex-empty.R |
|
| 400 |
#' @author N. Frerebeau |
|
| 401 |
#' @docType methods |
|
| 402 |
#' @family data cleaning tools |
|
| 403 |
#' @aliases remove_empty-method |
|
| 404 |
setGeneric( |
|
| 405 |
name = "remove_empty", |
|
| 406 | 4x |
def = function(x, ...) standardGeneric("remove_empty")
|
| 407 |
) |
|
| 408 | ||
| 409 |
#' Replace Empty String |
|
| 410 |
#' |
|
| 411 |
#' Replaces empty strings. |
|
| 412 |
#' @inheritParams detect |
|
| 413 |
#' @param value A possible replacement value. |
|
| 414 |
#' @param ... Currently not used. |
|
| 415 |
#' @example inst/examples/ex-empty.R |
|
| 416 |
#' @author N. Frerebeau |
|
| 417 |
#' @docType methods |
|
| 418 |
#' @family data cleaning tools |
|
| 419 |
#' @aliases replace_empty-method |
|
| 420 |
setGeneric( |
|
| 421 |
name = "replace_empty", |
|
| 422 | 2x |
def = function(x, ...) standardGeneric("replace_empty")
|
| 423 |
) |
|
| 424 | ||
| 425 |
## Constant -------------------------------------------------------------------- |
|
| 426 |
#' Remove Constant Columns |
|
| 427 |
#' |
|
| 428 |
#' @param x An \R object (should be a [`matrix`] or a [`data.frame`]). |
|
| 429 |
#' @param na.rm A [`logical`] scalar: should `NA` values be stripped before the |
|
| 430 |
#' computation proceeds? |
|
| 431 |
#' @param verbose A [`logical`] scalar: should \R report extra information |
|
| 432 |
#' on progress? |
|
| 433 |
#' @param ... Currently not used. |
|
| 434 |
#' @example inst/examples/ex-constant.R |
|
| 435 |
#' @author N. Frerebeau |
|
| 436 |
#' @docType methods |
|
| 437 |
#' @family data cleaning tools |
|
| 438 |
#' @aliases remove_constant-method |
|
| 439 |
setGeneric( |
|
| 440 |
name = "remove_constant", |
|
| 441 | 3x |
def = function(x, ...) standardGeneric("remove_constant")
|
| 442 |
) |
|
| 443 | ||
| 444 |
## Whitespace ------------------------------------------------------------------ |
|
| 445 |
#' Remove Leading/Trailing Whitespace |
|
| 446 |
#' |
|
| 447 |
#' @param x An \R object (should be a [`matrix`] or a [`data.frame`]). |
|
| 448 |
#' @param which A [`character`] string specifying whether to remove `both` |
|
| 449 |
#' leading and trailing whitespace (default), or only leading ("`left`") or
|
|
| 450 |
#' trailing ("`right`").
|
|
| 451 |
#' @param squish A [`logical`] scalar: should all internal whitespace be |
|
| 452 |
#' replaced with a single space? |
|
| 453 |
#' @param ... Currently not used. |
|
| 454 |
#' @example inst/examples/ex-whitespace.R |
|
| 455 |
#' @seealso [trimws()] |
|
| 456 |
#' @author N. Frerebeau |
|
| 457 |
#' @docType methods |
|
| 458 |
#' @family data cleaning tools |
|
| 459 |
#' @aliases clean_whitespace-method |
|
| 460 |
setGeneric( |
|
| 461 |
name = "clean_whitespace", |
|
| 462 | 5x |
def = function(x, ...) standardGeneric("clean_whitespace")
|
| 463 |
) |
|
| 464 | ||
| 465 |
# Data summary ================================================================= |
|
| 466 |
#' Data Description |
|
| 467 |
#' |
|
| 468 |
#' Describes an object. |
|
| 469 |
#' @param x An \R object (should be a [`matrix`] or a [`data.frame`]). |
|
| 470 |
#' @param ... Currently not used. |
|
| 471 |
#' @return |
|
| 472 |
#' `describe()` is called for its side-effects. Invisibly returns `x`. |
|
| 473 |
#' @example inst/examples/ex-describe.R |
|
| 474 |
#' @author N. Frerebeau |
|
| 475 |
#' @docType methods |
|
| 476 |
#' @family data summaries |
|
| 477 |
#' @aliases describe-method |
|
| 478 |
setGeneric( |
|
| 479 |
name = "describe", |
|
| 480 | 1x |
def = function(x, ...) standardGeneric("describe")
|
| 481 |
) |
|
| 482 | ||
| 483 |
#' Sparsity |
|
| 484 |
#' |
|
| 485 |
#' Computes data sparsity (proportion of zeros). |
|
| 486 |
#' @param x An \R object (should be a [`matrix`] or a [`data.frame`]). |
|
| 487 |
#' @param count A [`logical`] scalar: should a count be returned instead of a |
|
| 488 |
#' proportion? |
|
| 489 |
#' @param ... Currently not used. |
|
| 490 |
#' @details |
|
| 491 |
#' If `x` is a `data.frame`, sparsity is computed on `numeric` variables only. |
|
| 492 |
#' @return |
|
| 493 |
#' A length-one [`numeric`] vector. |
|
| 494 |
#' @example inst/examples/ex-describe.R |
|
| 495 |
#' @author N. Frerebeau |
|
| 496 |
#' @docType methods |
|
| 497 |
#' @family data summaries |
|
| 498 |
#' @aliases sparsity-method |
|
| 499 |
setGeneric( |
|
| 500 |
name = "sparsity", |
|
| 501 | 3x |
def = function(x, ...) standardGeneric("sparsity")
|
| 502 |
) |
|
| 503 | ||
| 504 |
# Mathematics ================================================================== |
|
| 505 |
#' Least Common Multiple |
|
| 506 |
#' |
|
| 507 |
#' Computes the lowest common multiple of the denominators of a set of |
|
| 508 |
#' fractions. |
|
| 509 |
#' @param x,y A [`numeric`] vector. |
|
| 510 |
#' @return A [`numeric`] vector. |
|
| 511 |
#' @author N. Frerebeau |
|
| 512 |
#' @docType methods |
|
| 513 |
#' @family mathematic functions |
|
| 514 |
#' @aliases math_lcm-method |
|
| 515 |
setGeneric( |
|
| 516 |
name = "math_lcm", |
|
| 517 | 1x |
def = function(x, y) standardGeneric("math_lcm")
|
| 518 |
) |
|
| 519 | ||
| 520 |
#' Greatest Common Divisor |
|
| 521 |
#' |
|
| 522 |
#' Computes the greatest common divisor (GCD) of two integer using the Euclidean |
|
| 523 |
#' algorithm. |
|
| 524 |
#' @param x,y A [`numeric`] vector. |
|
| 525 |
#' @return A [`numeric`] vector. |
|
| 526 |
#' @author N. Frerebeau |
|
| 527 |
#' @docType methods |
|
| 528 |
#' @family mathematic functions |
|
| 529 |
#' @aliases math_gcd-method |
|
| 530 |
setGeneric( |
|
| 531 |
name = "math_gcd", |
|
| 532 | 12x |
def = function(x, y) standardGeneric("math_gcd")
|
| 533 |
) |
|
| 534 | ||
| 535 |
# Statistics =================================================================== |
|
| 536 |
## Interval -------------------------------------------------------------------- |
|
| 537 |
#' Highest Density Regions |
|
| 538 |
#' |
|
| 539 |
#' @param x A [`numeric`] vector giving the coordinates of the points where |
|
| 540 |
#' the density is estimated. |
|
| 541 |
#' @param y A [`numeric`] vector giving the estimated density values. |
|
| 542 |
#' If `y` is missing and `x` is a `numeric` vector, density estimates will be |
|
| 543 |
#' computed from `x`. |
|
| 544 |
#' @param level A length-one [`numeric`] vector giving the confidence level. |
|
| 545 |
#' @param ... Further arguments to be passed to [stats::density()]. |
|
| 546 |
#' @return |
|
| 547 |
#' A three-columns `numeric` [`matrix`] giving the lower and upper boundaries |
|
| 548 |
#' of the HPD interval and associated probabilities. |
|
| 549 |
#' @references |
|
| 550 |
#' Hyndman, R. J. (1996). Computing and graphing highest density regions. |
|
| 551 |
#' *American Statistician*, 50: 120-126. \doi{10.2307/2684423}.
|
|
| 552 |
#' @example inst/examples/ex-interval.R |
|
| 553 |
#' @author N. Frerebeau |
|
| 554 |
#' @family summary statistics |
|
| 555 |
#' @docType methods |
|
| 556 |
#' @aliases interval_hdr-method |
|
| 557 |
setGeneric( |
|
| 558 |
name = "interval_hdr", |
|
| 559 | 2x |
def = function(x, y, ...) standardGeneric("interval_hdr")
|
| 560 |
) |
|
| 561 | ||
| 562 |
#' Bayesian Credible Interval |
|
| 563 |
#' |
|
| 564 |
#' Computes the shortest credible interval within which an unobserved parameter |
|
| 565 |
#' value falls with a particular probability. |
|
| 566 |
#' @param x A [`numeric`] vector. |
|
| 567 |
#' @param level A length-one [`numeric`] vector giving the confidence level. |
|
| 568 |
#' @param ... Currently not used. |
|
| 569 |
#' @return |
|
| 570 |
#' A three-columns `numeric` [`matrix`] giving the lower and upper boundaries |
|
| 571 |
#' of the credible interval and associated probability. |
|
| 572 |
#' @example inst/examples/ex-interval.R |
|
| 573 |
#' @author N. Frerebeau |
|
| 574 |
#' @family summary statistics |
|
| 575 |
#' @docType methods |
|
| 576 |
#' @aliases interval_credible-method |
|
| 577 |
setGeneric( |
|
| 578 |
name = "interval_credible", |
|
| 579 | 1x |
def = function(x, ...) standardGeneric("interval_credible")
|
| 580 |
) |
|
| 581 | ||
| 582 |
## Confidence ------------------------------------------------------------------ |
|
| 583 |
#' Confidence Interval for a Mean |
|
| 584 |
#' |
|
| 585 |
#' Computes a confidence interval for a mean at a desired level of significance. |
|
| 586 |
#' @param object A [`numeric`] vector. |
|
| 587 |
#' @param level A length-one [`numeric`] vector giving the confidence level. |
|
| 588 |
#' Must be a single number between \eqn{0} and \eqn{1}.
|
|
| 589 |
#' @param type A [`character`] string giving the type of confidence |
|
| 590 |
#' interval to be returned. It must be one "`student`" (the default) or |
|
| 591 |
#' "`normal`". Any unambiguous substring can be given. |
|
| 592 |
#' @param ... Currently not used. |
|
| 593 |
#' @return A length-two [`numeric`] vector giving the lower and upper confidence |
|
| 594 |
#' limits. |
|
| 595 |
#' @example inst/examples/ex-statistics.R |
|
| 596 |
#' @author N. Frerebeau |
|
| 597 |
#' @docType methods |
|
| 598 |
#' @family summary statistics |
|
| 599 |
#' @aliases confidence_mean-method |
|
| 600 |
setGeneric( |
|
| 601 |
name = "confidence_mean", |
|
| 602 | 2x |
def = function(object, ...) standardGeneric("confidence_mean")
|
| 603 |
) |
|
| 604 | ||
| 605 |
#' Confidence Interval for Binomial Proportions |
|
| 606 |
#' |
|
| 607 |
#' Computes Wald interval for a proportion at a desired level of significance. |
|
| 608 |
#' @param object A [`numeric`] vector giving the number of success. |
|
| 609 |
#' @param n A length-one [`numeric`] vector giving the number of trials. |
|
| 610 |
#' @param level A length-one [`numeric`] vector giving the confidence level. |
|
| 611 |
#' Must be a single number between \eqn{0} and \eqn{1}.
|
|
| 612 |
#' @param method A [`character`] string specifying the method to be used. |
|
| 613 |
#' Any unambiguous substring can be used. |
|
| 614 |
#' @param corrected A [`logical`] scalar: should continuity correction be used? |
|
| 615 |
#' Only used if `method` is "`wald`". |
|
| 616 |
#' @param ... Currently not used. |
|
| 617 |
#' @return A length-two [`numeric`] vector giving the lower and upper confidence |
|
| 618 |
#' limits. |
|
| 619 |
#' @example inst/examples/ex-statistics.R |
|
| 620 |
#' @author N. Frerebeau |
|
| 621 |
#' @docType methods |
|
| 622 |
#' @family summary statistics |
|
| 623 |
#' @aliases confidence_binomial-method |
|
| 624 |
setGeneric( |
|
| 625 |
name = "confidence_binomial", |
|
| 626 | 9x |
def = function(object, ...) standardGeneric("confidence_binomial")
|
| 627 |
) |
|
| 628 | ||
| 629 |
#' Confidence Interval for Multinomial Proportions |
|
| 630 |
#' |
|
| 631 |
#' Computes Wald interval for a proportion at a desired level of significance. |
|
| 632 |
#' @param object A [`numeric`] vector of positive integers giving the number of |
|
| 633 |
#' occurrences of each class. |
|
| 634 |
#' @param level A length-one [`numeric`] vector giving the confidence level. |
|
| 635 |
#' Must be a single number between \eqn{0} and \eqn{1}.
|
|
| 636 |
#' @param method A [`character`] string specifying the method to be used. |
|
| 637 |
#' Any unambiguous substring can be used. |
|
| 638 |
#' @param corrected A [`logical`] scalar: should continuity correction be used? |
|
| 639 |
#' Only used if `method` is "`wald`". |
|
| 640 |
#' @param ... Currently not used. |
|
| 641 |
#' @return A two column [`numeric`] `matrix` giving the lower and upper |
|
| 642 |
#' confidence limits. |
|
| 643 |
#' @example inst/examples/ex-statistics.R |
|
| 644 |
#' @author N. Frerebeau |
|
| 645 |
#' @docType methods |
|
| 646 |
#' @family summary statistics |
|
| 647 |
#' @aliases confidence_multinomial-method |
|
| 648 |
setGeneric( |
|
| 649 |
name = "confidence_multinomial", |
|
| 650 | 2x |
def = function(object, ...) standardGeneric("confidence_multinomial")
|
| 651 |
) |
|
| 652 | ||
| 653 |
#' Nonparametric Bootstrap Confidence Interval |
|
| 654 |
#' |
|
| 655 |
#' Computes equi-tailed two-sided nonparametric confidence interval. |
|
| 656 |
#' @param object A [`numeric`] vector giving the bootstrap replicates of the |
|
| 657 |
#' statistic of interest. |
|
| 658 |
#' @param level A length-one [`numeric`] vector giving the confidence level. |
|
| 659 |
#' Must be a single number between \eqn{0} and \eqn{1}.
|
|
| 660 |
#' @param type A [`character`] string giving the type of confidence |
|
| 661 |
#' interval to be returned. It must be one "`basic`" (the default), |
|
| 662 |
#' "`student`", "`normal`" or "`percentiles`". Any unambiguous substring can be |
|
| 663 |
#' given. |
|
| 664 |
#' @param t0 A length-one [`numeric`] vector giving the observed value of the |
|
| 665 |
#' statistic of interest. Must be defined if `type` is "`basic`", "`student`" |
|
| 666 |
#' or "`normal`". |
|
| 667 |
#' @param var_t0 A length-one [`numeric`] vector giving an estimate of the |
|
| 668 |
#' variance of the statistic of interest. Must be defined if `type` is |
|
| 669 |
#' "`student`". If `var_t0` is undefined and `type` is "`normal`, it defaults |
|
| 670 |
#' to `var(object)`. |
|
| 671 |
#' @param var_t A [`numeric`] vector giving the variances of the bootstrap |
|
| 672 |
#' replicates of the variable of interest. Must be defined if `type` is |
|
| 673 |
#' "`student`". |
|
| 674 |
#' @param ... Currently not used. |
|
| 675 |
#' @return A length-two [`numeric`] vector giving the lower and upper confidence |
|
| 676 |
#' limits. |
|
| 677 |
#' @references |
|
| 678 |
#' Davison, A. C. & Hinkley, D. V. (1997). *Bootstrap Methods and Their |
|
| 679 |
#' Application*. Cambridge Series on Statistical and Probabilistic Mathematics. |
|
| 680 |
#' Cambridge: Cambridge University Press. |
|
| 681 |
#' @seealso [bootstrap()] |
|
| 682 |
#' @example inst/examples/ex-bootstrap.R |
|
| 683 |
#' @author N. Frerebeau |
|
| 684 |
#' @docType methods |
|
| 685 |
#' @family summary statistics |
|
| 686 |
#' @aliases confidence_bootstrap-method |
|
| 687 |
setGeneric( |
|
| 688 |
name = "confidence_bootstrap", |
|
| 689 | 5x |
def = function(object, ...) standardGeneric("confidence_bootstrap")
|
| 690 |
) |
|
| 691 | ||
| 692 |
# Resampling =================================================================== |
|
| 693 |
#' Draw Uniform Random Sample |
|
| 694 |
#' |
|
| 695 |
#' Draws a random (sub)sample (with or without replacement). |
|
| 696 |
#' @param object A [`numeric`] vector. |
|
| 697 |
#' @param n A non-negative [`integer`] specifying the number of random vector |
|
| 698 |
#' to draw. |
|
| 699 |
#' @param size A non-negative [`integer`] specifying the sample size. |
|
| 700 |
#' @param replace A [`logical`] scalar: should sampling be with replacement? |
|
| 701 |
#' @param ... Currently not used. |
|
| 702 |
#' @return |
|
| 703 |
#' A `numeric` [`matrix`] with `n` rows and `size` columns. |
|
| 704 |
#' @example inst/examples/ex-resample.R |
|
| 705 |
#' @author N. Frerebeau |
|
| 706 |
#' @docType methods |
|
| 707 |
#' @family resampling methods |
|
| 708 |
#' @aliases resample_uniform-method |
|
| 709 |
setGeneric( |
|
| 710 |
name = "resample_uniform", |
|
| 711 | 1x |
def = function(object, ...) standardGeneric("resample_uniform")
|
| 712 |
) |
|
| 713 | ||
| 714 |
#' Draw Multinomial Random Sample |
|
| 715 |
#' |
|
| 716 |
#' Draws a random (sub)sample from a multinomial distribution. |
|
| 717 |
#' @param object A length-\eqn{k} [`integer`] vector, specifying the probability
|
|
| 718 |
#' for the \eqn{k} classes; is internally normalized to sum to 1.
|
|
| 719 |
#' @param n A non-negative [`integer`] specifying the number of random vector |
|
| 720 |
#' to draw. |
|
| 721 |
#' @param size A non-negative [`integer`] specifying the sample size. |
|
| 722 |
#' @param ... Currently not used. |
|
| 723 |
#' @return |
|
| 724 |
#' A `numeric` [`matrix`] with `n` rows and `k` columns. |
|
| 725 |
#' @seealso [stats::rmultinom()] |
|
| 726 |
#' @example inst/examples/ex-resample.R |
|
| 727 |
#' @author N. Frerebeau |
|
| 728 |
#' @docType methods |
|
| 729 |
#' @family resampling methods |
|
| 730 |
#' @aliases resample_multinomial-method |
|
| 731 |
setGeneric( |
|
| 732 |
name = "resample_multinomial", |
|
| 733 | 1x |
def = function(object, ...) standardGeneric("resample_multinomial")
|
| 734 |
) |
|
| 735 | ||
| 736 |
## Bootstrap ------------------------------------------------------------------- |
|
| 737 |
#' Nonparametric Bootstrap Estimation |
|
| 738 |
#' |
|
| 739 |
#' Samples randomly from the elements of `object` with replacement. |
|
| 740 |
#' @param object A [`numeric`] vector. |
|
| 741 |
#' @param do A [`function`] that takes `object` as an argument and returns a |
|
| 742 |
#' single numeric value. |
|
| 743 |
#' @param n A non-negative [`integer`] giving the number of bootstrap |
|
| 744 |
#' replications. |
|
| 745 |
#' @param f A [`function`] that takes a single numeric vector (the result of |
|
| 746 |
#' `do`) as argument. |
|
| 747 |
#' @param level A length-one [`numeric`] vector giving the confidence level. |
|
| 748 |
#' Must be a single number between \eqn{0} and \eqn{1}. Only used if `f` is
|
|
| 749 |
#' `NULL`. |
|
| 750 |
#' @param interval A [`character`] string giving the type of confidence |
|
| 751 |
#' interval to be returned. It must be one "`basic`" (the default), "`normal`" |
|
| 752 |
#' or "`percentiles`" (see [confidence_bootstrap()]). Any unambiguous substring |
|
| 753 |
#' can be given. Only used if `f` is `NULL`. |
|
| 754 |
#' @param ... Extra arguments to be passed to `do`. |
|
| 755 |
#' @return |
|
| 756 |
#' If `f` is `NULL` (the default), `bootstrap()` returns a named `numeric` |
|
| 757 |
#' vector with the following elements: |
|
| 758 |
#' \describe{
|
|
| 759 |
#' \item{`original`}{The observed value of `do` applied to `object`.}
|
|
| 760 |
#' \item{`mean`}{The bootstrap estimate of mean of `do`.}
|
|
| 761 |
#' \item{`bias`}{The bootstrap estimate of bias of `do`.}
|
|
| 762 |
#' \item{`error`}{The bootstrap estimate of standard error of `do`.}
|
|
| 763 |
#' \item{`lower`}{The lower limit of the bootstrap confidence interval at `level`.}
|
|
| 764 |
#' \item{`upper`}{The upper limit of the bootstrap confidence interval at `level`}
|
|
| 765 |
#' } |
|
| 766 |
#' |
|
| 767 |
#' If `f` is a `function`, `bootstrap()` returns the result of `f` applied to |
|
| 768 |
#' the `n` values of `do`. |
|
| 769 |
#' @references |
|
| 770 |
#' Davison, A. C. & Hinkley, D. V. (1997). *Bootstrap Methods and Their |
|
| 771 |
#' Application*. Cambridge Series on Statistical and Probabilistic Mathematics. |
|
| 772 |
#' Cambridge: Cambridge University Press. |
|
| 773 |
#' @seealso [confidence_bootstrap()] |
|
| 774 |
#' @example inst/examples/ex-bootstrap.R |
|
| 775 |
#' @author N. Frerebeau |
|
| 776 |
#' @docType methods |
|
| 777 |
#' @family resampling methods |
|
| 778 |
#' @aliases bootstrap-method |
|
| 779 |
setGeneric( |
|
| 780 |
name = "bootstrap", |
|
| 781 | 2x |
def = function(object, ...) standardGeneric("bootstrap")
|
| 782 |
) |
|
| 783 | ||
| 784 |
## Jackknife ------------------------------------------------------------------- |
|
| 785 |
#' Jackknife Estimation |
|
| 786 |
#' |
|
| 787 |
#' @param object A [`numeric`] vector. |
|
| 788 |
#' @param do A [`function`] that takes `object` as an argument and returns a |
|
| 789 |
#' single numeric value. |
|
| 790 |
#' @param ... Extra arguments to be passed to `do`. |
|
| 791 |
#' @param f A [`function`] that takes a single numeric vector (the leave-one-out |
|
| 792 |
#' values of `do`) as argument. |
|
| 793 |
#' @return |
|
| 794 |
#' If `f` is `NULL` (the default), `jackknife()` returns a named `numeric` |
|
| 795 |
#' vector with the following elements: |
|
| 796 |
#' \describe{
|
|
| 797 |
#' \item{`original`}{The observed value of `do` applied to `object`.}
|
|
| 798 |
#' \item{`mean`}{The jackknife estimate of mean of `do`.}
|
|
| 799 |
#' \item{`bias`}{The jackknife estimate of bias of `do`.}
|
|
| 800 |
#' \item{`error`}{The jackknife estimate of standard error of `do`.}
|
|
| 801 |
#' } |
|
| 802 |
#' |
|
| 803 |
#' If `f` is a `function`, `jackknife()` returns the result of `f` applied to |
|
| 804 |
#' the leave-one-out values of `do`. |
|
| 805 |
#' @example inst/examples/ex-jackknife.R |
|
| 806 |
#' @author N. Frerebeau |
|
| 807 |
#' @docType methods |
|
| 808 |
#' @family resampling methods |
|
| 809 |
#' @aliases jackknife-method |
|
| 810 |
setGeneric( |
|
| 811 |
name = "jackknife", |
|
| 812 | 2x |
def = function(object, ...) standardGeneric("jackknife")
|
| 813 |
) |
| 1 |
# DATA CLEANING: APPEND |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
#' @export |
|
| 6 |
#' @rdname append_rownames |
|
| 7 |
#' @aliases append_rownames,data.frame-method |
|
| 8 |
setMethod( |
|
| 9 |
f = "append_rownames", |
|
| 10 |
signature = c(x = "data.frame"), |
|
| 11 |
definition = function(x, after = 0, remove = TRUE, var = "rownames") {
|
|
| 12 | 1x |
assert_scalar(after, "numeric") |
| 13 | 1x |
assert_scalar(remove, "logical") |
| 14 | 1x |
assert_scalar(var, "character") |
| 15 | ||
| 16 | 1x |
n <- ncol(x) |
| 17 | 1x |
if (after > n) after <- n |
| 18 | 1x |
i_before <- seq_len(after) |
| 19 | 1x |
i_after <- if (after < n) seq(from = after + 1, to = n, by = 1) else 0 |
| 20 | ||
| 21 | 1x |
z <- rownames(x) |
| 22 | 1x |
x <- cbind(x[, i_before, drop = FALSE], z, x[, i_after, drop = FALSE]) |
| 23 | ||
| 24 | 1x |
colnames(x)[after + 1] <- var |
| 25 | 1x |
rownames(x) <- if (remove) NULL else z |
| 26 | ||
| 27 | 1x |
x |
| 28 |
} |
|
| 29 |
) |
|
| 30 | ||
| 31 |
#' @export |
|
| 32 |
#' @rdname append_column |
|
| 33 |
#' @aliases append_column,data.frame-method |
|
| 34 |
setMethod( |
|
| 35 |
f = "append_column", |
|
| 36 |
signature = c(x = "data.frame"), |
|
| 37 |
definition = function(x, column, after = 0, var = ".col") {
|
|
| 38 | 3x |
assert_scalar(after, "numeric") |
| 39 | 3x |
assert_scalar(var, "character") |
| 40 | 3x |
if (!is_atomic(column)) {
|
| 41 | ! |
stop(sprintf("%s must be an atomic vector.", sQuote("x")), call. = FALSE)
|
| 42 |
} |
|
| 43 | ||
| 44 | 3x |
m <- nrow(x) |
| 45 | 3x |
if (has_rownames(x) && has_names(column)) {
|
| 46 | 2x |
i <- match(names(column), rownames(x)) |
| 47 | ||
| 48 | 2x |
if (anyNA(i)) {
|
| 49 | 1x |
column <- column[!is.na(i)] |
| 50 | 1x |
i <- i[!is.na(i)] |
| 51 |
} |
|
| 52 | ||
| 53 | 2x |
old_column <- column |
| 54 | 2x |
column <- rep(NA, m) |
| 55 | 2x |
column[i] <- old_column |
| 56 |
} |
|
| 57 | ||
| 58 | 3x |
assert_length(column, m) |
| 59 | ||
| 60 | 2x |
p <- ncol(x) |
| 61 | 2x |
if (after > p) after <- p |
| 62 | 2x |
i_before <- seq_len(after) |
| 63 | 2x |
i_after <- if (after < p) seq(from = after + 1, to = p, by = 1) else 0 |
| 64 | ||
| 65 | 2x |
x <- cbind(x[, i_before, drop = FALSE], column, x[, i_after, drop = FALSE]) |
| 66 | ||
| 67 | 2x |
colnames(x)[after + 1] <- var |
| 68 | 2x |
x |
| 69 |
} |
|
| 70 |
) |
| 1 |
# CLEAN |
|
| 2 | ||
| 3 |
# Whitespace =================================================================== |
|
| 4 |
#' @export |
|
| 5 |
#' @rdname clean_whitespace |
|
| 6 |
#' @aliases clean_whitespace,data.frame-method |
|
| 7 |
setMethod( |
|
| 8 |
f = "clean_whitespace", |
|
| 9 |
signature = c(x = "data.frame"), |
|
| 10 |
definition = function(x, which = c("both", "left", "right"), squish = TRUE) {
|
|
| 11 | 4x |
x[] <- lapply( |
| 12 | 4x |
X = x, |
| 13 | 4x |
FUN = function(x, which, squish) {
|
| 14 | 4x |
if (!is.character(x)) return(x) |
| 15 | 4x |
trim(x, which = which, squish = squish) |
| 16 |
}, |
|
| 17 | 4x |
which = which, |
| 18 | 4x |
squish = squish |
| 19 |
) |
|
| 20 | 4x |
x |
| 21 |
} |
|
| 22 |
) |
|
| 23 | ||
| 24 |
#' @export |
|
| 25 |
#' @rdname clean_whitespace |
|
| 26 |
#' @aliases clean_whitespace,matrix-method |
|
| 27 |
setMethod( |
|
| 28 |
f = "clean_whitespace", |
|
| 29 |
signature = c(x = "matrix"), |
|
| 30 |
definition = function(x, which = c("both", "left", "right"), squish = TRUE) {
|
|
| 31 | 1x |
x[] <- trim(x, which = which, squish = squish) |
| 32 | 1x |
x |
| 33 |
} |
|
| 34 |
) |
|
| 35 | ||
| 36 |
trim <- function(x, which = c("both", "left", "right"), squish = TRUE) {
|
|
| 37 |
## Squish |
|
| 38 | 2x |
if (squish) x <- gsub(pattern = "\\s+", replacement = " ", x = x) |
| 39 |
## Trim |
|
| 40 | 5x |
x <- trimws(x, which = which, whitespace = "[ \t\r\n]") |
| 41 | ||
| 42 | 5x |
x |
| 43 |
} |
|
| 44 | ||
| 45 |
#' Wrap Character Strings to Format Paragraphs |
|
| 46 |
#' |
|
| 47 |
#' @param x A [`character`] vector of strings. |
|
| 48 |
#' @param width A positive [`integer`] giving the target column width for |
|
| 49 |
#' wrapping lines in the output. |
|
| 50 |
#' @return A [`character`] vector of strings. |
|
| 51 |
#' @keywords internal |
|
| 52 |
#' @noRd |
|
| 53 |
wrap_strings <- function(x, width, ...) {
|
|
| 54 | ! |
vapply( |
| 55 | ! |
X = x, |
| 56 | ! |
FUN = function(x, ...) {
|
| 57 | ! |
paste0(strwrap(x, width = width, ...), collapse = "\n") |
| 58 |
}, |
|
| 59 | ! |
FUN.VALUE = character(1), |
| 60 |
... |
|
| 61 |
) |
|
| 62 |
} |
| 1 |
# DATA SUMMARY: SPARCITY |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
#' @export |
|
| 6 |
#' @rdname sparsity |
|
| 7 |
#' @aliases sparsity,matrix-method |
|
| 8 |
setMethod( |
|
| 9 |
f = "sparsity", |
|
| 10 |
signature = c(x = "matrix"), |
|
| 11 |
definition = function(x, count = FALSE) {
|
|
| 12 | ! |
zeros <- sum(count(x, f = is_zero_numeric, margin = 2, na.rm = TRUE)) |
| 13 | ! |
if (count) return(zeros) |
| 14 | ||
| 15 |
## Proportion |
|
| 16 | ! |
total <- prod(dim(x)) |
| 17 | ! |
zeros / total |
| 18 |
} |
|
| 19 |
) |
|
| 20 | ||
| 21 |
#' @export |
|
| 22 |
#' @rdname sparsity |
|
| 23 |
#' @aliases sparsity,data.frame-method |
|
| 24 |
setMethod( |
|
| 25 |
f = "sparsity", |
|
| 26 |
signature = c(x = "data.frame"), |
|
| 27 |
definition = function(x, count = FALSE) {
|
|
| 28 | 3x |
zeros <- sum(count(x, f = is_zero_numeric, margin = 2, na.rm = TRUE)) |
| 29 | 1x |
if (count) return(zeros) |
| 30 | ||
| 31 |
## Count numeric values only |
|
| 32 | 2x |
num <- vapply(X = x, FUN = is.numeric, FUN.VALUE = logical(1)) |
| 33 | 2x |
total <- nrow(x) * sum(num) |
| 34 | ||
| 35 |
## Proportion |
|
| 36 | 2x |
zeros / total |
| 37 |
} |
|
| 38 |
) |
| 1 |
# PREDICATES |
|
| 2 | ||
| 3 |
# Not exported ================================================================= |
|
| 4 |
is_zero_numeric <- function(x, tolerance = sqrt(.Machine$double.eps)) {
|
|
| 5 | 35x |
if (is.numeric(x)) return(abs(x) <= tolerance) |
| 6 | 14x |
rep(FALSE, length(x)) |
| 7 |
} |
|
| 8 | ||
| 9 |
# Attributes =================================================================== |
|
| 10 |
#' Attributes Predicates |
|
| 11 |
#' |
|
| 12 |
#' * `has_length()` checks how long is an object. |
|
| 13 |
#' * `is_empty()` checks is an object is empty (any zero-length dimensions). |
|
| 14 |
#' @param x A [`vector`] to be tested. |
|
| 15 |
#' @param n A length-one [`numeric`] vector specifying the length to test `x` |
|
| 16 |
#' with. If `NULL`, returns `TRUE` if `x` has length greater than zero, and |
|
| 17 |
#' `FALSE` otherwise. |
|
| 18 |
#' @return A [`logical`] scalar. |
|
| 19 |
#' @family predicates |
|
| 20 |
#' @name predicate-attributes |
|
| 21 |
#' @rdname predicate-attributes |
|
| 22 |
NULL |
|
| 23 | ||
| 24 |
#' @export |
|
| 25 |
#' @rdname predicate-attributes |
|
| 26 |
has_length <- function(x, n = NULL) {
|
|
| 27 | 16x |
if (is.null(n)) length(x) > 0 else length(x) == n |
| 28 |
} |
|
| 29 | ||
| 30 |
#' @export |
|
| 31 |
#' @rdname predicate-attributes |
|
| 32 |
is_empty <- function(x) {
|
|
| 33 | 17x |
if (!is.null(dim(x))) nrow(x) == 0 || ncol(x) == 0 |
| 34 | 8x |
else length(x) == 0 |
| 35 |
} |
|
| 36 | ||
| 37 |
# Names ======================================================================== |
|
| 38 |
#' Names Predicates |
|
| 39 |
#' |
|
| 40 |
#' Checks if an object is named. |
|
| 41 |
#' @param x A [`vector`] to be tested. |
|
| 42 |
#' @param names A [`character`] vector specifying the names to test `x` |
|
| 43 |
#' with. If `NULL`, returns `TRUE` if `x` has names, and `FALSE` otherwise. |
|
| 44 |
#' @return A [`logical`] scalar. |
|
| 45 |
#' @family predicates |
|
| 46 |
#' @name predicate-names |
|
| 47 |
#' @rdname predicate-names |
|
| 48 |
NULL |
|
| 49 | ||
| 50 |
#' @export |
|
| 51 |
#' @rdname predicate-names |
|
| 52 |
has_names <- function(x, names = NULL) {
|
|
| 53 | 9x |
if (is.null(names)) {
|
| 54 | 6x |
has_length(names(x)) |
| 55 |
} else {
|
|
| 56 | 3x |
identical(names(x), names) |
| 57 |
} |
|
| 58 |
} |
|
| 59 | ||
| 60 |
#' @export |
|
| 61 |
#' @rdname predicate-names |
|
| 62 |
has_rownames <- function(x, names = NULL) {
|
|
| 63 | 6x |
if (is.null(names)) {
|
| 64 | 4x |
has_length(rownames(x)) |
| 65 |
} else {
|
|
| 66 | 2x |
identical(rownames(x), names) |
| 67 |
} |
|
| 68 |
} |
|
| 69 | ||
| 70 |
#' @export |
|
| 71 |
#' @rdname predicate-names |
|
| 72 |
has_colnames <- function(x, names = NULL) {
|
|
| 73 | 3x |
if (is.null(names)) {
|
| 74 | 1x |
has_length(colnames(x)) |
| 75 |
} else {
|
|
| 76 | 2x |
identical(colnames(x), names) |
| 77 |
} |
|
| 78 |
} |
|
| 79 | ||
| 80 |
# NA/NaN/Inf/duplicates ======================================================== |
|
| 81 |
#' Utility Predicates |
|
| 82 |
#' |
|
| 83 |
#' * `has_missing()` and `has_infinite()` check if an object contains missing |
|
| 84 |
#' or infinite values. |
|
| 85 |
#' * `has_duplicates()` checks if an object has duplicated elements. |
|
| 86 |
#' @param x A [`vector`] to be tested. |
|
| 87 |
#' @param tolerance A [`numeric`] scalar giving the tolerance to check within |
|
| 88 |
#' (for `numeric` vector). |
|
| 89 |
#' @param na.rm A [`logical`] scalar: should missing values (including `NaN`) |
|
| 90 |
#' be omitted? |
|
| 91 |
#' @return A [`logical`] scalar. |
|
| 92 |
#' @family predicates |
|
| 93 |
#' @name predicate-data |
|
| 94 |
#' @rdname predicate-data |
|
| 95 |
NULL |
|
| 96 | ||
| 97 |
#' @export |
|
| 98 |
#' @rdname predicate-data |
|
| 99 |
has_missing <- function(x) {
|
|
| 100 | 3x |
any(is.na(x)) |
| 101 |
} |
|
| 102 | ||
| 103 |
#' @export |
|
| 104 |
#' @rdname predicate-data |
|
| 105 |
has_infinite <- function(x) {
|
|
| 106 | 3x |
any(is.infinite(x)) |
| 107 |
} |
|
| 108 | ||
| 109 |
#' @export |
|
| 110 |
#' @rdname predicate-data |
|
| 111 |
has_duplicates <- function(x) {
|
|
| 112 | 4x |
any(duplicated(x)) |
| 113 |
} |
|
| 114 | ||
| 115 |
is_duplicated <- function(x) {
|
|
| 116 | ! |
duplicated(x, fromLast = FALSE) | duplicated(x, fromLast = TRUE) |
| 117 |
} |
|
| 118 | ||
| 119 |
#' @export |
|
| 120 |
#' @rdname predicate-data |
|
| 121 |
is_unique <- function(x, tolerance = sqrt(.Machine$double.eps), na.rm = FALSE) {
|
|
| 122 | 2x |
if (na.rm) x <- stats::na.omit(x) |
| 123 | 13x |
if (is.numeric(x)) {
|
| 124 | 11x |
cte <- is_constant(x, tolerance = tolerance) |
| 125 | 3x |
if (is.na(cte)) cte <- FALSE |
| 126 |
} else {
|
|
| 127 | 2x |
cte <- length(unique(x)) == 1 |
| 128 |
} |
|
| 129 | 13x |
cte |
| 130 |
} |
|
| 131 | ||
| 132 |
# Type ========================================================================= |
|
| 133 |
#' Type Predicates |
|
| 134 |
#' |
|
| 135 |
#' @param x An object to be tested. |
|
| 136 |
#' @return A [`logical`] scalar. |
|
| 137 |
#' @family predicates |
|
| 138 |
#' @name predicate-type |
|
| 139 |
#' @rdname predicate-type |
|
| 140 |
NULL |
|
| 141 | ||
| 142 |
#' @export |
|
| 143 |
#' @rdname predicate-type |
|
| 144 |
is_list <- function(x) {
|
|
| 145 | 7x |
typeof(x) == "list" |
| 146 |
} |
|
| 147 |
#' @export |
|
| 148 |
#' @rdname predicate-type |
|
| 149 |
is_atomic <- function(x) {
|
|
| 150 | 14x |
typeof(x) %in% c("logical", "integer", "double",
|
| 151 | 14x |
"complex", "character", "raw") |
| 152 |
} |
|
| 153 |
#' @export |
|
| 154 |
#' @rdname predicate-type |
|
| 155 |
is_vector <- function(x) {
|
|
| 156 | 6x |
is_atomic(x) || is_list(x) |
| 157 |
} |
|
| 158 |
#' @export |
|
| 159 |
#' @rdname predicate-type |
|
| 160 |
is_numeric <- function(x) {
|
|
| 161 | 243x |
typeof(x) %in% c("integer", "double")
|
| 162 |
} |
|
| 163 |
#' @export |
|
| 164 |
#' @rdname predicate-type |
|
| 165 |
is_integer <- function(x) {
|
|
| 166 | 13x |
typeof(x) == "integer" |
| 167 |
} |
|
| 168 |
#' @export |
|
| 169 |
#' @rdname predicate-type |
|
| 170 |
is_double <- function(x) {
|
|
| 171 | 5x |
typeof(x) == "double" |
| 172 |
} |
|
| 173 |
#' @export |
|
| 174 |
#' @rdname predicate-type |
|
| 175 |
is_character <- function(x) {
|
|
| 176 | 31x |
typeof(x) == "character" |
| 177 |
} |
|
| 178 |
#' @export |
|
| 179 |
#' @rdname predicate-type |
|
| 180 |
is_logical <- function(x) {
|
|
| 181 | 43x |
typeof(x) == "logical" |
| 182 |
} |
|
| 183 |
#' @export |
|
| 184 |
#' @rdname predicate-type |
|
| 185 |
is_error <- function(x) {
|
|
| 186 | 2x |
inherits(x, "try-error") || inherits(x, "simpleError") || inherits(x, "error") |
| 187 |
} |
|
| 188 |
#' @export |
|
| 189 |
#' @rdname predicate-type |
|
| 190 |
is_warning <- function(x) {
|
|
| 191 | 1x |
inherits(x, "simpleWarning") || inherits(x, "warning") |
| 192 |
} |
|
| 193 |
#' @export |
|
| 194 |
#' @rdname predicate-type |
|
| 195 |
is_message <- function(x) {
|
|
| 196 | 1x |
inherits(x, "simpleMessage") || inherits(x, "message") |
| 197 |
} |
|
| 198 | ||
| 199 |
# Scalar ======================================================================= |
|
| 200 |
#' Scalar Type Predicates |
|
| 201 |
#' |
|
| 202 |
#' @param x An object to be tested. |
|
| 203 |
#' @return A [`logical`] scalar. |
|
| 204 |
#' @family predicates |
|
| 205 |
#' @name is_scalar |
|
| 206 |
#' @rdname is_scalar |
|
| 207 |
NULL |
|
| 208 | ||
| 209 |
#' @export |
|
| 210 |
#' @rdname is_scalar |
|
| 211 |
is_scalar_list <- function(x) {
|
|
| 212 | 3x |
is_list(x) && length(x) == 1 |
| 213 |
} |
|
| 214 |
#' @export |
|
| 215 |
#' @rdname is_scalar |
|
| 216 |
is_scalar_atomic <- function(x) {
|
|
| 217 | 3x |
is_atomic(x) && length(x) == 1 |
| 218 |
} |
|
| 219 |
#' @export |
|
| 220 |
#' @rdname is_scalar |
|
| 221 |
is_scalar_vector <- function(x) {
|
|
| 222 | 3x |
is_vector(x) && length(x) == 1 |
| 223 |
} |
|
| 224 |
#' @export |
|
| 225 |
#' @rdname is_scalar |
|
| 226 |
is_scalar_numeric <- function(x) {
|
|
| 227 | 31x |
is_numeric(x) && length(x) == 1 |
| 228 |
} |
|
| 229 |
#' @export |
|
| 230 |
#' @rdname is_scalar |
|
| 231 |
is_scalar_integer <- function(x) {
|
|
| 232 | 3x |
is_integer(x) && length(x) == 1 |
| 233 |
} |
|
| 234 |
#' @export |
|
| 235 |
#' @rdname is_scalar |
|
| 236 |
is_scalar_double <- function(x) {
|
|
| 237 | 3x |
is_double(x) && length(x) == 1 |
| 238 |
} |
|
| 239 |
#' @export |
|
| 240 |
#' @rdname is_scalar |
|
| 241 |
is_scalar_character <- function(x) {
|
|
| 242 | 9x |
is_character(x) && length(x) == 1 |
| 243 |
} |
|
| 244 |
#' @export |
|
| 245 |
#' @rdname is_scalar |
|
| 246 |
is_scalar_logical <- function(x) {
|
|
| 247 | 4x |
is_logical(x) && length(x) == 1 |
| 248 |
} |
|
| 249 | ||
| 250 |
# Numeric ====================================================================== |
|
| 251 |
#' Numeric Predicates |
|
| 252 |
#' |
|
| 253 |
#' Check numeric objects: |
|
| 254 |
#' * `is_zero()` checks if an object contains only zeros. |
|
| 255 |
#' * `is_odd()` and `is_even()` check if a number is odd or even, respectively. |
|
| 256 |
#' * `is_positive()` and `is_negative` check if an object contains only |
|
| 257 |
#' (strictly) positive or negative numbers. |
|
| 258 |
#' * `is_whole()` checks if an object only contains whole numbers. |
|
| 259 |
#' @param x A [`numeric`] object to be tested. |
|
| 260 |
#' @param tolerance A [`numeric`] scalar giving the tolerance to check within. |
|
| 261 |
#' @param strict A [`logical`] scalar: should strict inequality be used? |
|
| 262 |
#' @param ... Currently not used. |
|
| 263 |
#' @return A [`logical`] vector. |
|
| 264 |
#' @family predicates |
|
| 265 |
#' @name predicate-numeric |
|
| 266 |
#' @rdname predicate-numeric |
|
| 267 |
NULL |
|
| 268 | ||
| 269 |
#' @export |
|
| 270 |
#' @rdname predicate-numeric |
|
| 271 |
is_zero <- function(x, tolerance = sqrt(.Machine$double.eps), ...) {
|
|
| 272 | 77x |
assert_type(x, "numeric") |
| 273 | 77x |
abs(x) <= tolerance |
| 274 |
} |
|
| 275 |
#' @export |
|
| 276 |
#' @rdname predicate-numeric |
|
| 277 |
is_odd <- function(x, ...) { # impair
|
|
| 278 | 3x |
assert_type(x, "numeric") |
| 279 | 3x |
as.logical(x %% 2) |
| 280 |
} |
|
| 281 |
#' @export |
|
| 282 |
#' @rdname predicate-numeric |
|
| 283 |
is_even <- function(x, ...) { # pair
|
|
| 284 | 2x |
assert_type(x, "numeric") |
| 285 | 2x |
!as.logical(x %% 2) |
| 286 |
} |
|
| 287 |
#' @export |
|
| 288 |
#' @rdname predicate-numeric |
|
| 289 |
is_positive <- function(x, strict = FALSE, ...) {
|
|
| 290 | 7x |
assert_type(x, "numeric") |
| 291 | 2x |
if (strict) x > 0 else x >= 0 |
| 292 |
} |
|
| 293 |
#' @export |
|
| 294 |
#' @rdname predicate-numeric |
|
| 295 |
is_negative <- function(x, strict = FALSE, ...) {
|
|
| 296 | 4x |
assert_type(x, "numeric") |
| 297 | 1x |
if (strict) x < 0 else x <= 0 |
| 298 |
} |
|
| 299 |
#' @export |
|
| 300 |
#' @rdname predicate-numeric |
|
| 301 |
is_whole <- function(x, tolerance = sqrt(.Machine$double.eps), ...) {
|
|
| 302 | 9x |
assert_type(x, "numeric") |
| 303 | 8x |
abs(x - round(x, digits = 0)) <= tolerance |
| 304 |
} |
|
| 305 | ||
| 306 |
#' Numeric Trend Predicates |
|
| 307 |
#' |
|
| 308 |
#' Check numeric objects: |
|
| 309 |
#' * `is_constant()` checks for equality among all elements of a vector. |
|
| 310 |
#' * `is_increasing()` and `is_decreasing()` check if a sequence of numbers |
|
| 311 |
#' is monotonically increasing or decreasing, respectively. |
|
| 312 |
#' @param x,y A [`numeric`] object to be tested. |
|
| 313 |
#' @param tolerance A [`numeric`] scalar giving the tolerance to check within. |
|
| 314 |
#' @param strict A [`logical`] scalar: should strict inequality be used? |
|
| 315 |
#' @param na.rm A [`logical`] scalar: should missing values (including `NaN`) |
|
| 316 |
#' be omitted? |
|
| 317 |
#' @return A [`logical`] scalar. |
|
| 318 |
#' @family predicates |
|
| 319 |
#' @name predicate-trend |
|
| 320 |
#' @rdname predicate-trend |
|
| 321 |
NULL |
|
| 322 | ||
| 323 |
#' @export |
|
| 324 |
#' @rdname predicate-trend |
|
| 325 |
is_constant <- function(x, tolerance = sqrt(.Machine$double.eps), na.rm = FALSE) {
|
|
| 326 | 18x |
assert_type(x, "numeric") |
| 327 | 17x |
abs(max(x, na.rm = na.rm) - min(x, na.rm = na.rm)) <= tolerance |
| 328 |
} |
|
| 329 |
#' @export |
|
| 330 |
#' @rdname predicate-trend |
|
| 331 |
is_increasing <- function(x, na.rm = FALSE) {
|
|
| 332 | 8x |
assert_type(x, "numeric") |
| 333 | 1x |
if (na.rm) x <- stats::na.omit(x) |
| 334 | 7x |
all(x == cummax(x)) |
| 335 |
} |
|
| 336 |
#' @export |
|
| 337 |
#' @rdname predicate-trend |
|
| 338 |
is_decreasing <- function(x, na.rm = FALSE) {
|
|
| 339 | 7x |
assert_type(x, "numeric") |
| 340 | 1x |
if (na.rm) x <- stats::na.omit(x) |
| 341 | 6x |
all(x == cummin(x)) |
| 342 |
} |
|
| 343 |
#' @export |
|
| 344 |
#' @rdname predicate-trend |
|
| 345 |
is_greater <- function(x, y, strict = FALSE, na.rm = FALSE) {
|
|
| 346 | 4x |
assert_type(x, "numeric") |
| 347 | 4x |
assert_type(y, "numeric") |
| 348 | 4x |
z <- if (strict) x > y else x >= y |
| 349 | 4x |
all(z, na.rm = na.rm) |
| 350 |
} |
|
| 351 |
#' @export |
|
| 352 |
#' @rdname predicate-trend |
|
| 353 |
is_lower <- function(x, y, strict = FALSE, na.rm = FALSE) {
|
|
| 354 | 7x |
assert_type(x, "numeric") |
| 355 | 6x |
assert_type(y, "numeric") |
| 356 | 5x |
z <- if (strict) x < y else x <= y |
| 357 | 5x |
all(z, na.rm = na.rm) |
| 358 |
} |
|
| 359 | ||
| 360 |
# Matrix ======================================================================= |
|
| 361 |
#' Matrix Predicates |
|
| 362 |
#' |
|
| 363 |
#' * `is_square()` checks if a matrix is square. |
|
| 364 |
#' * `is_symmetric()` checks if a matrix is symmetric. |
|
| 365 |
#' @param x A [`matrix`] to be tested. |
|
| 366 |
#' @return A [`logical`] scalar. |
|
| 367 |
#' @family predicates |
|
| 368 |
#' @name predicate-matrix |
|
| 369 |
#' @rdname predicate-matrix |
|
| 370 |
NULL |
|
| 371 | ||
| 372 |
#' @export |
|
| 373 |
#' @rdname predicate-matrix |
|
| 374 |
is_square <- function(x) {
|
|
| 375 | 1x |
if (is.matrix(x)) nrow(x) == ncol(x) else FALSE |
| 376 |
} |
|
| 377 |
#' @export |
|
| 378 |
#' @rdname predicate-matrix |
|
| 379 |
is_symmetric <- function(x) {
|
|
| 380 | 1x |
if (is.matrix(x)) identical(x, t(x)) else FALSE |
| 381 |
} |
|
| 382 | ||
| 383 |
# Graph ======================================================================== |
|
| 384 |
# Graph Predicates |
|
| 385 |
# |
|
| 386 |
# `is_dag()` checks if a graph has a topological ordering (i.e. is a directed |
|
| 387 |
# acyclic graph) using Kahn's algorithm. |
|
| 388 |
# @param x An adjacency [`matrix`] to be tested. |
|
| 389 |
# @return A [`logical`] scalar. |
|
| 390 |
# @references |
|
| 391 |
# Kahn, A. B. (1962). Topological sorting of large networks. *Communications |
|
| 392 |
# of the ACM*, 5(11), p. 558-562. \doi{10.1145/368996.369025}.
|
|
| 393 |
# @family predicates |
|
| 394 |
# @keywords internal |
|
| 395 |
# @export |
|
| 396 |
# is_dag <- function(x) {
|
|
| 397 |
# # Get edges |
|
| 398 |
# G <- matrix2edges(x) |
|
| 399 |
# # Find nodes which have no incoming edges |
|
| 400 |
# S <- which(colSums(x) == 0) |
|
| 401 |
# # List that will contain the sorted elements |
|
| 402 |
# L <- list() |
|
| 403 |
# |
|
| 404 |
# if (length(S) == 0) |
|
| 405 |
# return(FALSE) |
|
| 406 |
# |
|
| 407 |
# k <- 1L |
|
| 408 |
# while (k == 1 || length(S) != 0) {
|
|
| 409 |
# # Remove a node n from S and add n to tail of L |
|
| 410 |
# n <- S[[1]] |
|
| 411 |
# S <- S[-1] |
|
| 412 |
# L <- append(L, n) |
|
| 413 |
# # For each node m with an edge e from n to m |
|
| 414 |
# e <- which(G[, 1] == n) |
|
| 415 |
# m <- G[e, 2] |
|
| 416 |
# # Do remove edge e from the graph |
|
| 417 |
# G <- G[-e, , drop = FALSE] |
|
| 418 |
# # If m has no other incoming edges then insert m into S |
|
| 419 |
# if (nrow(G) != 0) {
|
|
| 420 |
# m <- m[!(m %in% G[, 2])] |
|
| 421 |
# if (length(m) != 0) |
|
| 422 |
# S <- append(S, m) |
|
| 423 |
# } |
|
| 424 |
# k <- k + 1 |
|
| 425 |
# } |
|
| 426 |
# return(nrow(G) == 0) |
|
| 427 |
# } |
|
| 428 | ||
| 429 |
# matrix2edges <- function(from) {
|
|
| 430 |
# edges <- matrix(data = NA, nrow = 0, ncol = 2) |
|
| 431 |
# nodes <- seq_len(nrow(from)) |
|
| 432 |
# for (i in nodes) {
|
|
| 433 |
# to <- which(from[i, ]) |
|
| 434 |
# if (length(to) != 0) {
|
|
| 435 |
# e <- cbind(form = i, to = to) |
|
| 436 |
# edges <- rbind(edges, e) |
|
| 437 |
# } |
|
| 438 |
# } |
|
| 439 |
# |
|
| 440 |
# edges |
|
| 441 |
# } |
| 1 |
# STATISTICS |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# HPDI ========================================================================= |
|
| 6 |
#' @export |
|
| 7 |
#' @rdname interval_hdr |
|
| 8 |
#' @aliases interval_hdr,numeric,numeric-method |
|
| 9 |
setMethod( |
|
| 10 |
f = "interval_hdr", |
|
| 11 |
signature = c(x = "numeric", y = "numeric"), |
|
| 12 |
definition = function(x, y, level = 0.954) {
|
|
| 13 |
## Compute density |
|
| 14 | 1x |
y <- y / sum(y) |
| 15 | ||
| 16 |
## Order the sample (faster sorting with radix method) |
|
| 17 | 1x |
sorted <- sort(y, decreasing = TRUE, method = "radix") |
| 18 | 1x |
i <- min(which(cumsum(sorted) >= sum(y) * level)) |
| 19 | 1x |
h <- sorted[[i]] |
| 20 | 1x |
idx <- which(y >= h) |
| 21 | ||
| 22 | 1x |
gap <- which(diff(idx) > 1) |
| 23 | 1x |
inf <- idx[c(1, gap + 1)] |
| 24 | 1x |
sup <- idx[c(gap, length(idx))] |
| 25 | ||
| 26 | 1x |
int <- mapply(FUN = seq, from = inf, to = sup, |
| 27 | 1x |
SIMPLIFY = FALSE, USE.NAMES = FALSE) |
| 28 | 2x |
p <- vapply(X = int, FUN = function(i, y) { sum(y[i]) },
|
| 29 | 1x |
FUN.VALUE = numeric(1), y = y) |
| 30 | ||
| 31 | 1x |
cbind(start = x[inf], end = x[sup], p = round(p, digits = 2)) |
| 32 |
} |
|
| 33 |
) |
|
| 34 | ||
| 35 |
#' @export |
|
| 36 |
#' @rdname interval_hdr |
|
| 37 |
#' @aliases interval_hdr,numeric,missing-method |
|
| 38 |
setMethod( |
|
| 39 |
f = "interval_hdr", |
|
| 40 |
signature = c(x = "numeric", y = "missing"), |
|
| 41 |
definition = function(x, level = 0.954, ...) {
|
|
| 42 |
## Compute density |
|
| 43 | 1x |
d <- stats::density(x, ...) |
| 44 | 1x |
methods::callGeneric(x = d$x, y = d$y, level = level) |
| 45 |
} |
|
| 46 |
) |
|
| 47 | ||
| 48 |
# Credible interval ============================================================ |
|
| 49 |
#' @export |
|
| 50 |
#' @rdname interval_credible |
|
| 51 |
#' @aliases interval_credible,numeric-method |
|
| 52 |
setMethod( |
|
| 53 |
f = "interval_credible", |
|
| 54 |
signature = "numeric", |
|
| 55 |
definition = function(x, level = 0.95) {
|
|
| 56 |
## Order the sample |
|
| 57 | 1x |
sorted <- sort(x, method = "radix") # Faster sorting with radix method |
| 58 | ||
| 59 |
## Sample size |
|
| 60 | 1x |
N <- length(x) |
| 61 | ||
| 62 |
## Number of data to be outside of the interval |
|
| 63 | 1x |
outside <- as.integer(N * (1 - level)) |
| 64 | 1x |
inf <- seq(from = 1L, to = outside + 1L, by = 1L) |
| 65 | 1x |
sup <- seq(from = N - outside, to = N, by = 1L) |
| 66 | ||
| 67 |
## Look for the shortest interval |
|
| 68 | 1x |
a <- sorted[sup] |
| 69 | 1x |
b <- sorted[inf] |
| 70 | 1x |
ind <- which.min(a - b) |
| 71 | ||
| 72 | 1x |
cbind(start = b[[ind]], end = a[[ind]], p = level) |
| 73 |
} |
|
| 74 |
) |
|
| 75 | ||
| 76 |
# Confidence interval ========================================================== |
|
| 77 |
#' @export |
|
| 78 |
#' @rdname confidence_mean |
|
| 79 |
#' @aliases confidence_mean,numeric-method |
|
| 80 |
setMethod( |
|
| 81 |
f = "confidence_mean", |
|
| 82 |
signature = c(object = "numeric"), |
|
| 83 |
definition = function(object, level = 0.95, type = c("student", "normal")) {
|
|
| 84 |
## Validation |
|
| 85 | 2x |
assert_scalar(level, "numeric") |
| 86 | ||
| 87 | 2x |
z <- zscore(level = level, n = length(object), type = type) |
| 88 | 2x |
margin <- z * stats::sd(object) / sqrt(length(object)) |
| 89 | 2x |
interval <- mean(object) + margin * c(-1, 1) |
| 90 | 2x |
names(interval) <- c("lower", "upper")
|
| 91 | 2x |
interval |
| 92 |
} |
|
| 93 |
) |
|
| 94 | ||
| 95 |
zscore <- function(level, n, type = c("student", "normal")) {
|
|
| 96 |
## Validation |
|
| 97 | 2x |
type <- match.arg(type, several.ok = FALSE) |
| 98 | ||
| 99 | 2x |
alpha <- 1 - level |
| 100 |
switch( |
|
| 101 | 2x |
type, |
| 102 | 1x |
normal = stats::qnorm(1 - alpha / 2), # Large sample size |
| 103 | 1x |
student = stats::qt(1 - alpha / 2, df = n - 1), # Small sample size |
| 104 |
) |
|
| 105 |
} |
|
| 106 | ||
| 107 |
#' @export |
|
| 108 |
#' @rdname confidence_binomial |
|
| 109 |
#' @aliases confidence_binomial,numeric-method |
|
| 110 |
setMethod( |
|
| 111 |
f = "confidence_binomial", |
|
| 112 |
signature = c(object = "numeric"), |
|
| 113 |
definition = function(object, n, level = 0.95, method = "wald", |
|
| 114 |
corrected = FALSE) {
|
|
| 115 |
## Validation |
|
| 116 | 9x |
assert_scalar(level, "numeric") |
| 117 | 9x |
method <- match.arg(method, several.ok = FALSE) |
| 118 | ||
| 119 | 9x |
p <- object / n |
| 120 | 9x |
q <- 1 - p |
| 121 | 9x |
alpha <- 1 - level |
| 122 | ||
| 123 | 9x |
z <- stats::qnorm(1 - alpha / 2) |
| 124 | 9x |
margin <- z * sqrt(p * q / n) |
| 125 | 9x |
if (corrected) {
|
| 126 | 4x |
margin <- margin + 1 / (2 * n) # Wald with continuity correction |
| 127 |
} |
|
| 128 | ||
| 129 | 9x |
interval <- c(lower = pmax(0, p - margin), upper = pmin(1, p + margin)) |
| 130 | 9x |
interval |
| 131 |
} |
|
| 132 |
) |
|
| 133 | ||
| 134 |
#' @export |
|
| 135 |
#' @rdname confidence_multinomial |
|
| 136 |
#' @aliases confidence_multinomial,numeric-method |
|
| 137 |
setMethod( |
|
| 138 |
f = "confidence_multinomial", |
|
| 139 |
signature = c(object = "numeric"), |
|
| 140 |
definition = function(object, level = 0.95, method = "wald", |
|
| 141 |
corrected = FALSE) {
|
|
| 142 |
## Validation |
|
| 143 | 2x |
assert_scalar(level, "numeric") |
| 144 | 2x |
method <- match.arg(method, several.ok = FALSE) |
| 145 | ||
| 146 | 2x |
n <- sum(object) |
| 147 | 2x |
f <- switch ( |
| 148 | 2x |
method, |
| 149 | 2x |
wald = function(x) confidence_binomial(x, n = n, level = level, |
| 150 | 2x |
method = "wald", |
| 151 | 2x |
corrected = corrected) |
| 152 |
) |
|
| 153 | ||
| 154 | 2x |
interval <- vapply(X = object, FUN = f, FUN.VALUE = numeric(2)) |
| 155 | 2x |
interval <- t(interval) |
| 156 | 2x |
rownames(interval) <- names(object) |
| 157 | 2x |
interval |
| 158 |
} |
|
| 159 |
) |
|
| 160 | ||
| 161 |
#' @export |
|
| 162 |
#' @rdname confidence_bootstrap |
|
| 163 |
#' @aliases confidence_bootstrap,numeric-method |
|
| 164 |
setMethod( |
|
| 165 |
f = "confidence_bootstrap", |
|
| 166 |
signature = c(object = "numeric"), |
|
| 167 |
definition = function(object, level = 0.95, |
|
| 168 |
type = c("basic", "normal", "student", "percentiles"),
|
|
| 169 |
t0 = NULL, var_t0 = NULL, var_t = NULL, ...) {
|
|
| 170 |
## Validation |
|
| 171 | 5x |
type <- match.arg(type, several.ok = FALSE) |
| 172 | 5x |
assert_scalar(level, "numeric") |
| 173 | 5x |
if (is.null(var_t)) {
|
| 174 | 4x |
fin <- which(is.finite(object)) |
| 175 |
} else {
|
|
| 176 | 1x |
assert_length(var_t, length(object)) |
| 177 | 1x |
assert_type(var_t, "numeric") |
| 178 | 1x |
fin <- which(is.finite(object) & is.finite(var_t)) |
| 179 | 1x |
var_t <- var_t[fin] |
| 180 |
} |
|
| 181 | 5x |
object <- object[fin] |
| 182 | ||
| 183 | 5x |
if (type == "percentiles" | type == "basic") {
|
| 184 |
## Percentile confidence interval |
|
| 185 |
# conf <- stats::quantile(object, probs = probs, names = FALSE) |
|
| 186 | 3x |
probs <- (1 + c(-level, level)) / 2 |
| 187 | 3x |
conf <- qq(object, probs) |
| 188 |
} |
|
| 189 | 5x |
if (type == "basic") {
|
| 190 |
## Basic bootstrap confidence limits (Davison & Hinkley, 1997) |
|
| 191 | 2x |
assert_scalar(t0, "numeric") |
| 192 | 2x |
conf <- 2 * t0 - rev(conf) |
| 193 |
} |
|
| 194 | 5x |
if (type == "normal") {
|
| 195 |
## Normal approximation (Davison & Hinkley, 1997) |
|
| 196 | 1x |
assert_scalar(t0, "numeric") |
| 197 | 1x |
if (is.null(var_t0)) var_t0 <- stats::var(object) |
| 198 | ||
| 199 | 1x |
bias <- mean(object) - t0 |
| 200 | 1x |
zscore <- sqrt(var_t0) * stats::qnorm((1 + level) / 2) |
| 201 | 1x |
conf <- c(t0 - bias - zscore, t0 - bias + zscore) |
| 202 |
} |
|
| 203 | 5x |
if (type == "student") {
|
| 204 |
## Studentized bootstrap confidence limits (Davison & Hinkley, 1997) |
|
| 205 | 1x |
assert_scalar(t0, "numeric") |
| 206 | 1x |
assert_scalar(var_t0, "numeric") |
| 207 | ||
| 208 | 1x |
probs <- (1 + c(level, -level)) / 2 |
| 209 | 1x |
zscore <- (object - t0) / sqrt(var_t) |
| 210 | 1x |
conf <- t0 - sqrt(var_t0) * qq(zscore, probs) |
| 211 |
} |
|
| 212 | ||
| 213 | 5x |
names(conf) <- c("lower", "upper")
|
| 214 | 5x |
conf |
| 215 |
} |
|
| 216 |
) |
|
| 217 | ||
| 218 |
# Copy non-exported from boot |
|
| 219 |
# Davison and Hinkley (1997), eq. 5.8 |
|
| 220 |
qq <- function(x, alpha) {
|
|
| 221 | 4x |
x <- x[is.finite(x)] |
| 222 | 4x |
R <- length(x) |
| 223 | 4x |
rk <- (R + 1) * alpha |
| 224 | 4x |
if (!all(rk > 1 & rk < R)) |
| 225 | 3x |
warning(tr_("Extreme order statistics used as endpoints."), call. = FALSE)
|
| 226 | 4x |
k <- trunc(rk) |
| 227 | 4x |
inds <- seq_along(k) |
| 228 | 4x |
out <- inds |
| 229 | 4x |
kvs <- k[k > 0 & k < R] |
| 230 | 4x |
tstar <- sort(x, partial = sort(union(c(1, R), c(kvs, kvs + 1)))) |
| 231 | 4x |
ints <- (k == rk) |
| 232 | ! |
if (any(ints)) out[inds[ints]] <- tstar[k[inds[ints]]] |
| 233 | 4x |
out[k == 0] <- tstar[1L] |
| 234 | 4x |
out[k == R] <- tstar[R] |
| 235 | 4x |
not <- function(v) xor(rep(TRUE,length(v)), v) |
| 236 | 4x |
temp <- inds[not(ints) & k != 0 & k != R] |
| 237 | 4x |
temp1 <- stats::qnorm(alpha[temp]) |
| 238 | 4x |
temp2 <- stats::qnorm(k[temp] / (R + 1)) |
| 239 | 4x |
temp3 <- stats::qnorm((k[temp] + 1) / (R + 1)) |
| 240 | 4x |
tk <- tstar[k[temp]] |
| 241 | 4x |
tk1 <- tstar[k[temp] + 1L] |
| 242 | 4x |
out[temp] <- tk + (temp1 - temp2) / (temp3 - temp2) * (tk1 - tk) |
| 243 | 4x |
out |
| 244 |
} |
|
| 245 | ||
| 246 |
# Bootstrap ==================================================================== |
|
| 247 |
#' @export |
|
| 248 |
#' @rdname bootstrap |
|
| 249 |
#' @aliases bootstrap,numeric-method |
|
| 250 |
setMethod( |
|
| 251 |
f = "bootstrap", |
|
| 252 |
signature = c(object = "numeric"), |
|
| 253 |
definition = function(object, do, n, ..., f = NULL, level = 0.95, |
|
| 254 |
interval = c("basic", "normal", "percentiles")) {
|
|
| 255 | 2x |
interval <- match.arg(interval, several.ok = FALSE) |
| 256 | ||
| 257 | 2x |
hat <- do(object, ...) |
| 258 | ||
| 259 | 2x |
spl <- sample(object, size = length(object) * n, replace = TRUE) |
| 260 | 2x |
replicates <- t(matrix(spl, nrow = n)) |
| 261 | 2x |
values <- apply(X = replicates, MARGIN = 2, FUN = do, ...) |
| 262 | ||
| 263 | 1x |
if (is.function(f)) return(f(values)) |
| 264 | 1x |
summary_bootstrap(values, hat, level = level, interval = interval) |
| 265 |
} |
|
| 266 |
) |
|
| 267 | ||
| 268 |
summary_bootstrap <- function(x, hat, level = 0.95, interval = "basic") {
|
|
| 269 | 1x |
n <- length(x) |
| 270 | 1x |
boot_mean <- mean(x) |
| 271 | 1x |
boot_bias <- boot_mean - hat |
| 272 | 1x |
boot_error <- stats::sd(x) |
| 273 | ||
| 274 | 1x |
ci <- confidence_bootstrap(x, level = level, t0 = hat, type = interval) |
| 275 | 1x |
results <- c(hat, boot_mean, boot_bias, boot_error, ci) |
| 276 | 1x |
names(results) <- c("original", "mean", "bias", "error", "lower", "upper")
|
| 277 | 1x |
results |
| 278 |
} |
|
| 279 | ||
| 280 |
# Jaccknife ==================================================================== |
|
| 281 |
#' @export |
|
| 282 |
#' @rdname jackknife |
|
| 283 |
#' @aliases jackknife,numeric-method |
|
| 284 |
setMethod( |
|
| 285 |
f = "jackknife", |
|
| 286 |
signature = c(object = "numeric"), |
|
| 287 |
definition = function(object, do, ..., f = NULL) {
|
|
| 288 | 2x |
n <- length(object) |
| 289 | 2x |
hat <- do(object, ...) |
| 290 | ||
| 291 | 2x |
values <- vapply( |
| 292 | 2x |
X = seq_len(n), |
| 293 | 2x |
FUN = function(i, x, do, ...) {
|
| 294 | 40x |
do(x[-i], ...) |
| 295 |
}, |
|
| 296 | 2x |
FUN.VALUE = double(1), |
| 297 | 2x |
x = object, do = do, ... |
| 298 |
) |
|
| 299 | ||
| 300 | 1x |
if (is.function(f)) return(f(values)) |
| 301 | 1x |
summary_jackknife(values, hat) |
| 302 |
} |
|
| 303 |
) |
|
| 304 | ||
| 305 |
summary_jackknife <- function(x, hat) {
|
|
| 306 | 1x |
n <- length(x) |
| 307 | 1x |
jack_mean <- mean(x) |
| 308 | 1x |
jack_bias <- (n - 1) * (jack_mean - hat) |
| 309 | 1x |
jack_error <- sqrt(((n - 1) / n) * sum((x - jack_mean)^2)) |
| 310 | ||
| 311 | 1x |
results <- c(hat, jack_mean, jack_bias, jack_error) |
| 312 | 1x |
names(results) <- c("original", "mean", "bias", "error")
|
| 313 | 1x |
results |
| 314 |
} |
|
| 315 | ||
| 316 |
# Resample ===================================================================== |
|
| 317 |
#' @export |
|
| 318 |
#' @rdname resample_uniform |
|
| 319 |
#' @aliases resample_uniform,numeric-method |
|
| 320 |
setMethod( |
|
| 321 |
f = "resample_uniform", |
|
| 322 |
signature = c(object = "numeric"), |
|
| 323 |
definition = function(object, n, size = length(object), replace = FALSE, ...) {
|
|
| 324 | 1x |
spl <- replicate( |
| 325 | 1x |
n = n, |
| 326 | 1x |
expr = sample(object, size = size, replace = replace), |
| 327 | 1x |
simplify = FALSE |
| 328 |
) |
|
| 329 | 1x |
do.call(rbind, spl) |
| 330 |
} |
|
| 331 |
) |
|
| 332 | ||
| 333 |
#' @export |
|
| 334 |
#' @rdname resample_multinomial |
|
| 335 |
#' @aliases resample_multinomial,numeric-method |
|
| 336 |
setMethod( |
|
| 337 |
f = "resample_multinomial", |
|
| 338 |
signature = c(object = "numeric"), |
|
| 339 |
definition = function(object, n, size = sum(object), ...) {
|
|
| 340 | 1x |
prob <- object / sum(object) |
| 341 | 1x |
t(stats::rmultinom(n, size = size, prob = prob)) |
| 342 |
} |
|
| 343 |
) |
| 1 |
# CHECK DATA INPUT |
|
| 2 |
#' @include predicates.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
#' Validate a Condition |
|
| 6 |
#' |
|
| 7 |
#' @param expr An object to be evaluated. |
|
| 8 |
#' @return |
|
| 9 |
#' Returns `NULL` on success, otherwise returns the error as a string. |
|
| 10 |
#' @author N. Frerebeau |
|
| 11 |
#' @family validation methods |
|
| 12 |
#' @name validate |
|
| 13 |
#' @rdname validate |
|
| 14 |
#' @export |
|
| 15 |
validate <- function(expr) {
|
|
| 16 | 3x |
cnd <- catch_message(eval(expr)) |
| 17 | 2x |
if (has_length(cnd)) return(cnd) |
| 18 | 1x |
NULL |
| 19 |
} |
|
| 20 | ||
| 21 |
# Packages ===================================================================== |
|
| 22 |
#' Check the Availability of a Package |
|
| 23 |
#' |
|
| 24 |
#' @param x A [`character`] vector naming the packages to check. |
|
| 25 |
#' @param ask A [`logical`] scalar: should the user be asked to select packages |
|
| 26 |
#' before they are downloaded and installed? |
|
| 27 |
#' @details |
|
| 28 |
#' `assert_package()` is designed for use inside other functions in your own |
|
| 29 |
#' package to check for the availability of a suggested package. |
|
| 30 |
#' |
|
| 31 |
#' If the required packages are not available and \R is running interactively, |
|
| 32 |
#' the user will be asked to install the packages. |
|
| 33 |
#' @return Invisibly returns `NULL`. |
|
| 34 |
#' @family checking methods |
|
| 35 |
#' @author N. Frerebeau |
|
| 36 |
#' @export |
|
| 37 |
assert_package <- function(x, ask = interactive()) {
|
|
| 38 | 1x |
ok <- vapply(X = x, FUN = requireNamespace, FUN.VALUE = logical(1), |
| 39 | 1x |
quietly = TRUE) |
| 40 | ||
| 41 | 1x |
miss <- x[!ok] |
| 42 | 1x |
n <- length(miss) |
| 43 | ||
| 44 | 1x |
if (n > 0) {
|
| 45 | 1x |
err <- sprintf( |
| 46 | 1x |
ngettext(n, "Package %s is required.", "Packages %s are required."), |
| 47 | 1x |
paste0(sQuote(miss), collapse = ", ") |
| 48 |
) |
|
| 49 | 1x |
install <- FALSE |
| 50 | 1x |
if (isTRUE(ask)) {
|
| 51 | ! |
msg <- ngettext(n, "Do you want to install it?", "Do you want to install them?") |
| 52 | ! |
install <- utils::askYesNo( |
| 53 | ! |
msg = paste0(c(err, msg), collapse = "\n"), |
| 54 | ! |
default = FALSE, |
| 55 | ! |
prompts = gettext(c("Yes", "No", "Cancel"))
|
| 56 |
) |
|
| 57 |
} |
|
| 58 | 1x |
if (isTRUE(install)) {
|
| 59 | ! |
utils::install.packages(miss) |
| 60 |
} else {
|
|
| 61 | 1x |
throw_error("error_missing_package", err)
|
| 62 |
} |
|
| 63 |
} |
|
| 64 | ! |
invisible(NULL) |
| 65 |
} |
|
| 66 | ||
| 67 |
# Attributes =================================================================== |
|
| 68 |
#' Check Object Length(s) |
|
| 69 |
#' |
|
| 70 |
#' @param x An object to be checked. |
|
| 71 |
#' @param expected An appropriate expected value. |
|
| 72 |
#' @param allow_empty A [`logical`] scalar: should [empty][is_empty()] object be |
|
| 73 |
#' ignored? |
|
| 74 |
#' @param allow_null A [`logical`] scalar: should `NULL` object be ignored? |
|
| 75 |
#' @param empty Deprecated. |
|
| 76 |
#' @return |
|
| 77 |
#' Throws an error, if any, and returns `x` invisibly otherwise. |
|
| 78 |
#' @author N. Frerebeau |
|
| 79 |
#' @family checking methods |
|
| 80 |
#' @export |
|
| 81 |
assert_length <- function(x, expected, allow_empty = empty, allow_null = FALSE, empty = FALSE) {
|
|
| 82 | 1x |
if (is.null(x) && isTRUE(allow_null)) return(invisible(NULL)) |
| 83 | ||
| 84 | 27x |
arg <- deparse(substitute(x)) |
| 85 | 27x |
if (!(allow_empty && is_empty(x)) && !has_length(x, n = expected)) {
|
| 86 | 4x |
txt <- tr_("%s must be of length %d; not %d.")
|
| 87 | 4x |
msg <- sprintf(txt, sQuote(arg), expected, length(x)) |
| 88 | 4x |
throw_error("error_bad_length", msg)
|
| 89 |
} |
|
| 90 | 23x |
invisible(x) |
| 91 |
} |
|
| 92 | ||
| 93 |
#' @export |
|
| 94 |
#' @rdname assert_length |
|
| 95 |
assert_lengths <- function(x, expected) {
|
|
| 96 | 2x |
arg <- deparse(substitute(x)) |
| 97 | 2x |
n <- lengths(x) |
| 98 | 2x |
if (!all(n == expected)) {
|
| 99 | 1x |
txt <- tr_("Elements of %s must be of lengths %s; not %s.")
|
| 100 | 1x |
msg <- sprintf(txt, sQuote(arg), paste0(expected, collapse = ", "), |
| 101 | 1x |
paste0(n, collapse = ", ")) |
| 102 | 1x |
throw_error("error_bad_length", msg)
|
| 103 |
} |
|
| 104 | 1x |
invisible(x) |
| 105 |
} |
|
| 106 | ||
| 107 |
#' Check Object Dimensions |
|
| 108 |
#' |
|
| 109 |
#' @param x An object to be checked. |
|
| 110 |
#' @param expected An appropriate expected value. |
|
| 111 |
#' @return |
|
| 112 |
#' Throws an error, if any, and returns `x` invisibly otherwise. |
|
| 113 |
#' @author N. Frerebeau |
|
| 114 |
#' @family checking methods |
|
| 115 |
#' @export |
|
| 116 |
assert_dim <- function(x, expected) {
|
|
| 117 | 2x |
arg <- deparse(substitute(x)) |
| 118 | 2x |
n <- dim(x) |
| 119 | 2x |
if (!all(n == expected)) {
|
| 120 | 1x |
txt <- tr_("%s must be of dimension %s; not %s.")
|
| 121 | 1x |
msg <- sprintf(txt, sQuote(arg), paste0(expected, collapse = " x "), |
| 122 | 1x |
paste0(n, collapse = " x ")) |
| 123 | 1x |
throw_error("error_bad_dimensions", msg)
|
| 124 |
} |
|
| 125 | 1x |
invisible(x) |
| 126 |
} |
|
| 127 | ||
| 128 |
#' @export |
|
| 129 |
#' @rdname assert_dim |
|
| 130 |
assert_nrow <- function(x, expected) {
|
|
| 131 | 1x |
arg <- deparse(substitute(x)) |
| 132 | 1x |
n <- nrow(x) |
| 133 | 1x |
if (n != expected) {
|
| 134 | 1x |
txt <- ngettext(expected, "%s must have %s row; not %s.", |
| 135 | 1x |
"%s must have %s rows; not %s.") |
| 136 | 1x |
msg <- sprintf(txt, sQuote(arg), expected, n) |
| 137 | 1x |
throw_error("error_bad_dimensions", msg)
|
| 138 |
} |
|
| 139 | ! |
invisible(x) |
| 140 |
} |
|
| 141 | ||
| 142 |
#' @export |
|
| 143 |
#' @rdname assert_dim |
|
| 144 |
assert_ncol <- function(x, expected) {
|
|
| 145 | 1x |
arg <- deparse(substitute(x)) |
| 146 | 1x |
n <- ncol(x) |
| 147 | 1x |
if (n != expected) {
|
| 148 | 1x |
txt <- ngettext(expected, "%s must have %s column; not %s.", |
| 149 | 1x |
"%s must have %s columns; not %s.") |
| 150 | 1x |
msg <- sprintf(txt, sQuote(arg), expected, n) |
| 151 | 1x |
throw_error("error_bad_dimensions", msg)
|
| 152 |
} |
|
| 153 | ! |
invisible(x) |
| 154 |
} |
|
| 155 | ||
| 156 |
#' Check Object Filling |
|
| 157 |
#' |
|
| 158 |
#' Checks if an object is (not) empty. |
|
| 159 |
#' @param x An object to be checked. |
|
| 160 |
#' @return |
|
| 161 |
#' Throws an error, if any, and returns `x` invisibly otherwise. |
|
| 162 |
#' @author N. Frerebeau |
|
| 163 |
#' @family checking methods |
|
| 164 |
#' @export |
|
| 165 |
assert_empty <- function(x) {
|
|
| 166 | 2x |
arg <- deparse(substitute(x)) |
| 167 | 2x |
if (!is_empty(x)) {
|
| 168 | 1x |
msg <- sprintf(tr_("%s must be empty."), sQuote(arg))
|
| 169 | 1x |
throw_error("error_bad_dimensions", msg)
|
| 170 |
} |
|
| 171 | 1x |
invisible(x) |
| 172 |
} |
|
| 173 | ||
| 174 |
#' @export |
|
| 175 |
#' @rdname assert_empty |
|
| 176 |
assert_filled <- function(x) {
|
|
| 177 | 18x |
arg <- deparse(substitute(x)) |
| 178 | 18x |
if (is_empty(x)) {
|
| 179 | 2x |
msg <- sprintf(tr_("%s must not be empty."), sQuote(arg))
|
| 180 | 2x |
throw_error("error_bad_dimensions", msg)
|
| 181 |
} |
|
| 182 | 16x |
invisible(x) |
| 183 |
} |
|
| 184 | ||
| 185 |
# Names ======================================================================== |
|
| 186 |
#' Check Object Names |
|
| 187 |
#' |
|
| 188 |
#' @param x An object to be checked. |
|
| 189 |
#' @param expected An appropriate expected value. |
|
| 190 |
#' @return |
|
| 191 |
#' Throws an error, if any, and returns `x` invisibly otherwise. |
|
| 192 |
#' @author N. Frerebeau |
|
| 193 |
#' @family checking methods |
|
| 194 |
#' @export |
|
| 195 |
assert_names <- function(x, expected = NULL) {
|
|
| 196 | 4x |
arg <- deparse(substitute(x)) |
| 197 | 4x |
if (!has_names(x, names = expected)) {
|
| 198 | 3x |
if (is.null(expected)) {
|
| 199 | 1x |
msg <- sprintf(tr_("%s must have names."), sQuote(arg))
|
| 200 |
} else {
|
|
| 201 | 2x |
msg <- sprintf(tr_("%s must have the following names: %s."),
|
| 202 | 2x |
sQuote(arg), paste0(expected, collapse = ", ")) |
| 203 |
} |
|
| 204 | 3x |
throw_error("error_bad_names", msg)
|
| 205 |
} |
|
| 206 | 1x |
invisible(x) |
| 207 |
} |
|
| 208 | ||
| 209 |
#' @export |
|
| 210 |
#' @rdname assert_names |
|
| 211 |
assert_rownames <- function(x, expected = NULL) {
|
|
| 212 | 3x |
arg <- deparse(substitute(x)) |
| 213 | 3x |
if (!has_rownames(x, names = expected)) {
|
| 214 | 2x |
if (is.null(expected)) {
|
| 215 | 1x |
msg <- sprintf(tr_("%s must have row names."), sQuote(arg))
|
| 216 |
} else {
|
|
| 217 | 1x |
msg <- sprintf(tr_("%s must have the following row names: %s."),
|
| 218 | 1x |
sQuote(arg), paste0(expected, collapse = ", ")) |
| 219 |
} |
|
| 220 | 2x |
throw_error("error_bad_names", msg)
|
| 221 |
} |
|
| 222 | 1x |
invisible(x) |
| 223 |
} |
|
| 224 | ||
| 225 |
#' @export |
|
| 226 |
#' @rdname assert_names |
|
| 227 |
assert_colnames <- function(x, expected = NULL) {
|
|
| 228 | 3x |
arg <- deparse(substitute(x)) |
| 229 | 3x |
if (!has_colnames(x, names = expected)) {
|
| 230 | 2x |
if (is.null(expected)) {
|
| 231 | 1x |
msg <- sprintf(tr_("%s must have column names."), sQuote(arg))
|
| 232 |
} else {
|
|
| 233 | 1x |
msg <- sprintf(tr_("%s must have the following column names: %s."),
|
| 234 | 1x |
sQuote(arg), paste0(expected, collapse = ", ")) |
| 235 |
} |
|
| 236 | 2x |
throw_error("error_bad_names", msg)
|
| 237 |
} |
|
| 238 | 1x |
invisible(x) |
| 239 |
} |
|
| 240 | ||
| 241 |
# NA/NaN/Inf/duplicates ======================================================== |
|
| 242 |
#' Check Missing Values |
|
| 243 |
#' |
|
| 244 |
#' Checks if an object contains any missing (`NA`, `NaN`) values. |
|
| 245 |
#' @param x An object to be checked. |
|
| 246 |
#' @return |
|
| 247 |
#' Throws an error, if any, and returns `x` invisibly otherwise. |
|
| 248 |
#' @author N. Frerebeau |
|
| 249 |
#' @family checking methods |
|
| 250 |
#' @export |
|
| 251 |
assert_missing <- function(x) {
|
|
| 252 | 3x |
arg <- deparse(substitute(x)) |
| 253 | 3x |
n <- sum(is.na(x)) |
| 254 | 3x |
if (n > 0) {
|
| 255 | 2x |
txt <- ngettext(n, "%s must not contain missing values (%d detected).", |
| 256 | 2x |
"%s must not contain missing values (%d detected).") |
| 257 | 2x |
msg <- sprintf(txt, sQuote(arg), n) |
| 258 | 2x |
throw_error("error_data_missing", msg)
|
| 259 |
} |
|
| 260 | 1x |
invisible(x) |
| 261 |
} |
|
| 262 | ||
| 263 |
#' Check Infinite Values |
|
| 264 |
#' |
|
| 265 |
#' Checks if an object contains any infinite (`Inf`) values. |
|
| 266 |
#' @param x An object to be checked. |
|
| 267 |
#' @return |
|
| 268 |
#' Throws an error, if any, and returns `x` invisibly otherwise. |
|
| 269 |
#' @author N. Frerebeau |
|
| 270 |
#' @family checking methods |
|
| 271 |
#' @export |
|
| 272 |
assert_infinite <- function(x) {
|
|
| 273 | 2x |
arg <- deparse(substitute(x)) |
| 274 | 2x |
n <- sum(is.infinite(x)) |
| 275 | 2x |
if (n > 0) {
|
| 276 | 1x |
txt <- ngettext(n, "%s must not contain infinite values (%d detected).", |
| 277 | 1x |
"%s must not contain infinite values (%d detected).") |
| 278 | 1x |
msg <- sprintf(txt, sQuote(arg), n) |
| 279 | 1x |
throw_error("error_data_infinite", msg)
|
| 280 |
} |
|
| 281 | 1x |
invisible(x) |
| 282 |
} |
|
| 283 | ||
| 284 |
#' Check Duplicates |
|
| 285 |
#' |
|
| 286 |
#' Checks if an object contains duplicated elements. |
|
| 287 |
#' @param x An object to be checked. |
|
| 288 |
#' @return |
|
| 289 |
#' Throws an error, if any, and returns `x` invisibly otherwise. |
|
| 290 |
#' @author N. Frerebeau |
|
| 291 |
#' @family checking methods |
|
| 292 |
#' @export |
|
| 293 |
assert_unique <- function(x) {
|
|
| 294 | 2x |
arg <- deparse(substitute(x)) |
| 295 | 2x |
if (has_duplicates(x)) {
|
| 296 | 1x |
msg <- sprintf(tr_("Elements of %s must be unique."), sQuote(arg))
|
| 297 | 1x |
throw_error("error_data_duplicates", msg)
|
| 298 |
} |
|
| 299 | 1x |
invisible(x) |
| 300 |
} |
|
| 301 | ||
| 302 |
# Types ======================================================================== |
|
| 303 |
#' Check Data Types |
|
| 304 |
#' |
|
| 305 |
#' @param x An object to be checked. |
|
| 306 |
#' @param expected A [`character`] string specifying the expected |
|
| 307 |
#' type. It must be one of "`list`", "`atomic`", "`vector`", "`numeric`", |
|
| 308 |
#' "`integer`", "`double`", "`character`" or "`logical`". |
|
| 309 |
#' @param allow_empty A [`logical`] scalar: should [empty][is_empty()] object be |
|
| 310 |
#' allowed? |
|
| 311 |
#' @param allow_null A [`logical`] scalar: should `NULL` object be ignored? |
|
| 312 |
#' @return |
|
| 313 |
#' Throws an error, if any, and returns `x` invisibly otherwise. |
|
| 314 |
#' @author N. Frerebeau |
|
| 315 |
#' @family checking methods |
|
| 316 |
#' @export |
|
| 317 |
assert_type <- function(x, expected, allow_empty = TRUE, allow_null = FALSE) {
|
|
| 318 | 15x |
if (is.null(x) && isTRUE(allow_null)) return(invisible(NULL)) |
| 319 | 1x |
if (isFALSE(allow_empty)) assert_filled(x) |
| 320 | ||
| 321 | 174x |
arg <- deparse(substitute(x)) |
| 322 | 174x |
msg <- sprintf(tr_("Can't find a predicate for this type: %s."), expected)
|
| 323 | 174x |
predicate <- switch( |
| 324 | 174x |
expected, |
| 325 | 174x |
list = is_list, |
| 326 | 174x |
atomic = is_atomic, |
| 327 | 174x |
vector = is_vector, |
| 328 | 174x |
numeric = is_numeric, |
| 329 | 174x |
integer = is_integer, |
| 330 | 174x |
double = is_double, |
| 331 | 174x |
character = is_character, |
| 332 | 174x |
logical = is_logical, |
| 333 | 174x |
stop(msg, call. = FALSE) |
| 334 |
) |
|
| 335 | 174x |
if (!predicate(x)) {
|
| 336 | 12x |
msg <- sprintf(tr_("%s must be %s; not %s."), sQuote(arg), expected, typeof(x))
|
| 337 | 12x |
throw_error("error_bad_type", msg)
|
| 338 |
} |
|
| 339 | 162x |
invisible(x) |
| 340 |
} |
|
| 341 | ||
| 342 |
#' @export |
|
| 343 |
#' @rdname assert_type |
|
| 344 |
assert_scalar <- function(x, expected) {
|
|
| 345 | 35x |
arg <- deparse(substitute(x)) |
| 346 | 35x |
msg <- sprintf(tr_("Can't find a predicate for this scalar: %s."), expected)
|
| 347 | 35x |
predicate <- switch( |
| 348 | 35x |
expected, |
| 349 | 35x |
list = is_scalar_list, |
| 350 | 35x |
atomic = is_scalar_atomic, |
| 351 | 35x |
vector = is_scalar_vector, |
| 352 | 35x |
numeric = is_scalar_numeric, |
| 353 | 35x |
integer = is_scalar_integer, |
| 354 | 35x |
double = is_scalar_double, |
| 355 | 35x |
character = is_scalar_character, |
| 356 | 35x |
logical = is_scalar_logical, |
| 357 | 35x |
stop(msg, call. = FALSE) |
| 358 |
) |
|
| 359 | 35x |
if (!predicate(x)) {
|
| 360 | 2x |
msg <- sprintf(tr_("%s must be a scalar (%s)."), sQuote(arg), expected)
|
| 361 | 2x |
throw_error("error_bad_scalar", msg)
|
| 362 |
} |
|
| 363 | 33x |
invisible(x) |
| 364 |
} |
|
| 365 | ||
| 366 |
#' @export |
|
| 367 |
#' @rdname assert_type |
|
| 368 |
assert_function <- function(x) {
|
|
| 369 | 92x |
arg <- deparse(substitute(x)) |
| 370 | 92x |
if (!is.function(x)) {
|
| 371 | 1x |
msg <- sprintf(tr_("%s must be a function."), sQuote(arg))
|
| 372 | 1x |
throw_error("error_bad_type", msg)
|
| 373 |
} |
|
| 374 | 91x |
invisible(x) |
| 375 |
} |
|
| 376 | ||
| 377 |
# Numeric ====================================================================== |
|
| 378 |
#' Check Numeric Values |
|
| 379 |
#' |
|
| 380 |
#' @param x A [`numeric`] object to be checked. |
|
| 381 |
#' @param na.rm A [`logical`] scalar: should missing values (including `NaN`) |
|
| 382 |
#' be omitted? |
|
| 383 |
#' @param ... Extra parameters to be passed to internal methods. |
|
| 384 |
#' @return |
|
| 385 |
#' Throws an error, if any, and returns `x` invisibly otherwise. |
|
| 386 |
#' @author N. Frerebeau |
|
| 387 |
#' @family checking methods |
|
| 388 |
#' @name assert_numeric |
|
| 389 |
#' @rdname assert_numeric |
|
| 390 |
NULL |
|
| 391 | ||
| 392 |
#' @export |
|
| 393 |
#' @rdname assert_numeric |
|
| 394 |
assert_count <- function(x, na.rm = FALSE, ...) {
|
|
| 395 | 4x |
arg <- deparse(substitute(x)) |
| 396 | 4x |
if (!all(is_whole(x, ...), na.rm = na.rm)) {
|
| 397 | 3x |
msg <- sprintf(tr_("%s must contain integers (counts)."), sQuote(arg))
|
| 398 | 3x |
throw_error("error_bad_numeric", msg)
|
| 399 |
} |
|
| 400 | 1x |
invisible(x) |
| 401 |
} |
|
| 402 | ||
| 403 |
#' @export |
|
| 404 |
#' @rdname assert_numeric |
|
| 405 |
assert_whole <- assert_count |
|
| 406 | ||
| 407 |
#' @export |
|
| 408 |
#' @rdname assert_numeric |
|
| 409 |
assert_positive <- function(x, na.rm = FALSE, ...) {
|
|
| 410 | 3x |
arg <- deparse(substitute(x)) |
| 411 | 3x |
if (!all(is_positive(x, ...), na.rm = na.rm)) {
|
| 412 | 2x |
msg <- sprintf(tr_("%s must contain positive numbers."), sQuote(arg))
|
| 413 | 2x |
throw_error("error_bad_numeric", msg)
|
| 414 |
} |
|
| 415 | 1x |
invisible(x) |
| 416 |
} |
|
| 417 | ||
| 418 |
#' @export |
|
| 419 |
#' @rdname assert_numeric |
|
| 420 |
assert_negative <- function(x, na.rm = FALSE, ...) {
|
|
| 421 | ! |
arg <- deparse(substitute(x)) |
| 422 | ! |
if (!all(is_negative(x, ...), na.rm = na.rm)) {
|
| 423 | ! |
msg <- sprintf(tr_("%s must contain negative numbers."), sQuote(arg))
|
| 424 | ! |
throw_error("error_bad_numeric", msg)
|
| 425 |
} |
|
| 426 | ! |
invisible(x) |
| 427 |
} |
|
| 428 | ||
| 429 |
#' @export |
|
| 430 |
#' @rdname assert_numeric |
|
| 431 |
assert_odd <- function(x, na.rm = FALSE, ...) {
|
|
| 432 | 1x |
arg <- deparse(substitute(x)) |
| 433 | 1x |
if (!all(is_odd(x, ...), na.rm = na.rm)) {
|
| 434 | 1x |
msg <- sprintf(tr_("%s must contain odd numbers."), sQuote(arg))
|
| 435 | 1x |
throw_error("error_bad_numeric", msg)
|
| 436 |
} |
|
| 437 | ! |
invisible(x) |
| 438 |
} |
|
| 439 | ||
| 440 |
#' @export |
|
| 441 |
#' @rdname assert_numeric |
|
| 442 |
assert_even <- function(x, na.rm = FALSE, ...) {
|
|
| 443 | 1x |
arg <- deparse(substitute(x)) |
| 444 | 1x |
if (!all(is_even(x, ...), na.rm = na.rm)) {
|
| 445 | 1x |
msg <- sprintf(tr_("%s must contain even numbers."), sQuote(arg))
|
| 446 | 1x |
throw_error("error_bad_numeric", msg)
|
| 447 |
} |
|
| 448 | ! |
invisible(x) |
| 449 |
} |
|
| 450 | ||
| 451 |
#' Check Numeric Trend |
|
| 452 |
#' |
|
| 453 |
#' @param x A [`numeric`] object to be checked. |
|
| 454 |
#' @param ... Extra parameters to be passed to internal methods. |
|
| 455 |
#' @return |
|
| 456 |
#' Throws an error, if any, and returns `x` invisibly otherwise. |
|
| 457 |
#' @author N. Frerebeau |
|
| 458 |
#' @family checking methods |
|
| 459 |
#' @export |
|
| 460 |
assert_constant <- function(x, ...) {
|
|
| 461 | 1x |
arg <- deparse(substitute(x)) |
| 462 | 1x |
if (!is_constant(x, ...)) {
|
| 463 | 1x |
msg <- sprintf(tr_("%s must be constant."), sQuote(arg))
|
| 464 | 1x |
throw_error("error_bad_numeric", msg)
|
| 465 |
} |
|
| 466 | ! |
invisible(x) |
| 467 |
} |
|
| 468 | ||
| 469 |
#' @export |
|
| 470 |
#' @rdname assert_constant |
|
| 471 |
assert_decreasing <- function(x, ...) {
|
|
| 472 | 1x |
arg <- deparse(substitute(x)) |
| 473 | 1x |
if (!is_decreasing(x, ...)) {
|
| 474 | 1x |
msg <- sprintf(tr_("%s must be decreasing."), sQuote(arg))
|
| 475 | 1x |
throw_error("error_bad_numeric", msg)
|
| 476 |
} |
|
| 477 | ! |
invisible(x) |
| 478 |
} |
|
| 479 | ||
| 480 |
#' @export |
|
| 481 |
#' @rdname assert_constant |
|
| 482 |
assert_increasing <- function(x, ...) {
|
|
| 483 | 2x |
arg <- deparse(substitute(x)) |
| 484 | 2x |
if (!is_increasing(x, ...)) {
|
| 485 | 1x |
msg <- sprintf(tr_("%s must be increasing."), sQuote(arg))
|
| 486 | 1x |
throw_error("error_bad_numeric", msg)
|
| 487 |
} |
|
| 488 | 1x |
invisible(x) |
| 489 |
} |
|
| 490 | ||
| 491 |
#' Check Numeric Relations |
|
| 492 |
#' |
|
| 493 |
#' @param x,y A [`numeric`] object to be checked. |
|
| 494 |
#' @param ... Extra parameters to be passed to internal methods. |
|
| 495 |
#' @return |
|
| 496 |
#' Throws an error, if any, and returns `x` invisibly otherwise. |
|
| 497 |
#' @author N. Frerebeau |
|
| 498 |
#' @family checking methods |
|
| 499 |
#' @export |
|
| 500 |
assert_lower <- function(x, y, ...) {
|
|
| 501 | 2x |
arg_x <- deparse(substitute(x)) |
| 502 | 2x |
arg_y <- deparse(substitute(y)) |
| 503 | 2x |
if (!is_lower(x, y, ...)) {
|
| 504 | 1x |
txt <- tr_("%s must be lower than %s.")
|
| 505 | 1x |
msg <- sprintf(txt, sQuote(arg_x), sQuote(arg_y)) |
| 506 | 1x |
throw_error("error_bad_numeric", msg)
|
| 507 |
} |
|
| 508 | 1x |
invisible(x) |
| 509 |
} |
|
| 510 | ||
| 511 |
#' @export |
|
| 512 |
#' @rdname assert_lower |
|
| 513 |
assert_greater <- function(x, y, ...) {
|
|
| 514 | 1x |
arg_x <- deparse(substitute(x)) |
| 515 | 1x |
arg_y <- deparse(substitute(y)) |
| 516 | 1x |
if (!is_greater(x, y, ...)) {
|
| 517 | 1x |
txt <- tr_("%s must be greater than %s.")
|
| 518 | 1x |
msg <- sprintf(txt, sQuote(arg_x), sQuote(arg_y)) |
| 519 | 1x |
throw_error("error_bad_numeric", msg)
|
| 520 |
} |
|
| 521 | ! |
invisible(x) |
| 522 |
} |
|
| 523 | ||
| 524 |
# Matrix ======================================================================= |
|
| 525 |
#' Check Matrix |
|
| 526 |
#' |
|
| 527 |
#' @param x A [`matrix`] to be checked. |
|
| 528 |
#' @return Throw an error, if any, and returns `x` invisibly otherwise. |
|
| 529 |
#' @author N. Frerebeau |
|
| 530 |
#' @family checking methods |
|
| 531 |
#' @export |
|
| 532 |
assert_square <- function(x) {
|
|
| 533 | 2x |
arg <- deparse(substitute(x)) |
| 534 | 2x |
if (!is_square(x)) {
|
| 535 | 1x |
k <- paste0(dim(x), collapse = " x ") |
| 536 | 1x |
msg <- sprintf(tr_("%s must be a square matrix, not %s."), sQuote(arg), k)
|
| 537 | 1x |
throw_error("error_bad_matrix", msg)
|
| 538 |
} |
|
| 539 | 1x |
invisible(x) |
| 540 |
} |
|
| 541 | ||
| 542 |
#' @export |
|
| 543 |
#' @rdname assert_square |
|
| 544 |
assert_symmetric <- function(x) {
|
|
| 545 | 1x |
arg <- deparse(substitute(x)) |
| 546 | 1x |
if (!is_symmetric(x)) {
|
| 547 | 1x |
msg <- sprintf(tr_("%s must be a symmetric matrix."), sQuote(arg))
|
| 548 | 1x |
throw_error("error_bad_matrix", msg)
|
| 549 |
} |
|
| 550 | ! |
invisible(x) |
| 551 |
} |
|
| 552 | ||
| 553 |
# Check Graph |
|
| 554 |
# |
|
| 555 |
# @param x A [`matrix`] to be checked. |
|
| 556 |
# @param expected An appropriate expected value. |
|
| 557 |
# @return Throw an error, if any. |
|
| 558 |
# @author N. Frerebeau |
|
| 559 |
# @family checking methods |
|
| 560 |
# @keywords internal |
|
| 561 |
# @export |
|
| 562 |
# assert_dag <- function(x) {
|
|
| 563 |
# arg <- deparse(substitute(x)) |
|
| 564 |
# if (!is_dag(x)) {
|
|
| 565 |
# msg <- sprintf(tr_("%s must not contain cycles."), sQuote(arg))
|
|
| 566 |
# throw_error("error_bad_graph", msg)
|
|
| 567 |
# } |
|
| 568 |
# invisible(x) |
|
| 569 |
# } |
| 1 |
# DATA SUMMARY: DESCRIBE |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
#' @export |
|
| 6 |
#' @rdname describe |
|
| 7 |
#' @aliases describe,ANY-method |
|
| 8 |
setMethod( |
|
| 9 |
f = "describe", |
|
| 10 |
signature = c(x = "ANY"), |
|
| 11 |
definition = function(x) {
|
|
| 12 |
## Variable types |
|
| 13 | 1x |
msg_var <- describe_variables(x) |
| 14 | ||
| 15 |
## Missing values |
|
| 16 | 1x |
msg_miss <- describe_missing(x) |
| 17 | ||
| 18 |
## Check |
|
| 19 | 1x |
msg_val <- describe_check(x) |
| 20 | ||
| 21 | 1x |
cat(msg_var, msg_miss, msg_val, sep = "\n") |
| 22 | ||
| 23 |
# tot <- list( |
|
| 24 |
# m = m, p = p, |
|
| 25 |
# n_numeric = n_num, n_categorial = n_cha, n_binary = n_bin, |
|
| 26 |
# row_missing = m_NA, col_missing = p_NA, |
|
| 27 |
# zero_values = spa, zero_variance = p_var |
|
| 28 |
# ) |
|
| 29 | ||
| 30 | 1x |
invisible(x) |
| 31 |
} |
|
| 32 |
) |
|
| 33 | ||
| 34 |
describe_variables <- function(x) {
|
|
| 35 | 1x |
m <- nrow(x) |
| 36 | 1x |
p <- ncol(x) |
| 37 | ||
| 38 | 1x |
msg_rows <- sprintf(ngettext(m, "%d observation", "%d observations"), m) |
| 39 | 1x |
msg_cols <- sprintf(ngettext(p, "%d variable", "%d variables"), p) |
| 40 | 1x |
title <- sprintf("%s, %s:", msg_rows, msg_cols)
|
| 41 | ||
| 42 | 1x |
num <- detect(x, f = is.numeric, margin = 2) |
| 43 | 1x |
bin <- detect(x, f = is.logical, margin = 2) |
| 44 | 1x |
n_num <- sum(num) |
| 45 | 1x |
n_bin <- sum(bin) |
| 46 | 1x |
n_cha <- sum(!num & !bin) |
| 47 | ||
| 48 | 1x |
msg_num <- sprintf(ngettext(n_num, "%d numeric variable", "%d numeric variables"), n_num) |
| 49 | 1x |
msg_bin <- sprintf(ngettext(n_bin, "%d binary variable", "%d binary variables"), n_bin) |
| 50 | 1x |
msg_cha <- sprintf(ngettext(n_cha, "%d categorial variable", "%d categorial variables"), n_cha) |
| 51 | ||
| 52 | 1x |
msg <- paste0(sprintf("\n* %s.", c(msg_num, msg_cha, msg_bin)), collapse = "")
|
| 53 | 1x |
paste0(title, msg, collapse = "") |
| 54 |
} |
|
| 55 |
describe_missing <- function(x) {
|
|
| 56 | 1x |
m <- nrow(x) |
| 57 | 1x |
p <- ncol(x) |
| 58 | ||
| 59 | 1x |
n_NA <- sum(count(x, f = is.na)) |
| 60 | 1x |
m_NA <- sum(detect(x, f = is.na, margin = 1)) |
| 61 | 1x |
p_NA <- sum(detect(x, f = is.na, margin = 2)) |
| 62 | 1x |
pc <- label_percent(c(m_NA / m, p_NA / p), digits = 1, trim = TRUE) |
| 63 | ||
| 64 | 1x |
title <- sprintf(ngettext(n_NA, "%d missing value:", "%d missing values:"), n_NA) |
| 65 | ||
| 66 | 1x |
rows_NA <- ngettext(m_NA, "%d observation (%s) contains missing values", |
| 67 | 1x |
"%d observations (%s) contain missing values") |
| 68 | 1x |
msg_row_NA <- sprintf(rows_NA, m_NA, pc[[1]]) |
| 69 | ||
| 70 | 1x |
cols_NA <- ngettext(p_NA, "%d variable (%s) contains missing values", |
| 71 | 1x |
"%d variables (%s) contain missing values") |
| 72 | 1x |
msg_col_NA <- sprintf(cols_NA, p_NA, pc[[2]]) |
| 73 | ||
| 74 | 1x |
msg <- paste0(sprintf("\n* %s.", c(msg_row_NA, msg_col_NA)), collapse = "")
|
| 75 | 1x |
paste0("\n", title, msg, collapse = "")
|
| 76 |
} |
|
| 77 |
describe_check <- function(x) {
|
|
| 78 | 1x |
title <- tr_("Data checking:")
|
| 79 | ||
| 80 |
## Constant columns |
|
| 81 | 1x |
p_var <- sum(detect(x, f = function(x) is_unique(x), margin = 2)) |
| 82 | 1x |
cols_var <- ngettext(p_var, "%d variable with no variance", |
| 83 | 1x |
"%d variables with no variance") |
| 84 | 1x |
msg_col_var <- sprintf(cols_var, p_var) |
| 85 | ||
| 86 |
## Sparsity |
|
| 87 | 1x |
spa <- sparsity(x, count = FALSE) |
| 88 | 1x |
msg_spa <- sprintf(tr_("%s of numeric values are zero"), label_percent(spa, digits = 1))
|
| 89 | ||
| 90 | 1x |
msg <- paste0(sprintf("\n* %s.", c(msg_spa, msg_col_var)), collapse = "")
|
| 91 | 1x |
paste0("\n", title, msg, collapse = "")
|
| 92 |
} |
|
| 93 | ||
| 94 |
#' Label Percentages |
|
| 95 |
#' |
|
| 96 |
#' @param x A [`numeric`] vector. |
|
| 97 |
#' @param digits An [`integer`] indicating the number of decimal places. |
|
| 98 |
#' If `NULL` (the default), breaks will have the minimum number of digits |
|
| 99 |
#' needed to show the difference between adjacent values. |
|
| 100 |
#' @param trim A [`logical`] scalar. If `FALSE` (the default), values are |
|
| 101 |
#' right-justified to a common width (see [base::format()]). |
|
| 102 |
#' @return A [`character`] vector. |
|
| 103 |
#' @keywords internal |
|
| 104 |
#' @export |
|
| 105 |
label_percent <- function(x, digits = NULL, trim = FALSE) {
|
|
| 106 | 4x |
i <- !is.na(x) |
| 107 | 4x |
y <- x[i] |
| 108 | 4x |
y <- abs(y) * 100 |
| 109 | 4x |
y <- format(y, trim = trim, digits = digits) |
| 110 | 4x |
y <- paste0(y, "%") |
| 111 | 4x |
x[i] <- y |
| 112 | 4x |
x |
| 113 |
} |
| 1 |
# GET |
|
| 2 | ||
| 3 |
#' @export |
|
| 4 |
#' @rdname get |
|
| 5 |
#' @aliases get_columns,ANY-method |
|
| 6 |
setMethod( |
|
| 7 |
f = "get_columns", |
|
| 8 |
signature = c(x = "ANY"), |
|
| 9 |
definition = function(x, select = NULL, names = NULL, ...) {
|
|
| 10 | 1x |
i <- seek_columns(x, select = select, names = names, ...) |
| 11 | 1x |
x[, i, drop = FALSE] |
| 12 |
} |
|
| 13 |
) |
|
| 14 | ||
| 15 |
#' @export |
|
| 16 |
#' @rdname get |
|
| 17 |
#' @aliases get_rows,ANY-method |
|
| 18 |
setMethod( |
|
| 19 |
f = "get_rows", |
|
| 20 |
signature = c(x = "ANY"), |
|
| 21 |
definition = function(x, select = NULL, names = NULL, ...) {
|
|
| 22 | 1x |
i <- seek_rows(x, select = select, names = names, ...) |
| 23 | 1x |
x[i, , drop = FALSE] |
| 24 |
} |
|
| 25 |
) |
| 1 |
# DATA CLEANING: DISCARD |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# discard ====================================================================== |
|
| 6 |
#' @export |
|
| 7 |
#' @rdname discard |
|
| 8 |
#' @aliases discard,ANY-method |
|
| 9 |
setMethod( |
|
| 10 |
f = "discard", |
|
| 11 |
signature = c(x = "ANY"), |
|
| 12 |
definition = function(x, f, margin = 1, negate = FALSE, all = FALSE, |
|
| 13 |
na.rm = FALSE, verbose = getOption("arkhe.verbose"),
|
|
| 14 |
...) {
|
|
| 15 | 39x |
i <- detect(x, f = f, margin = margin, negate = negate, all = all, |
| 16 | 39x |
na.rm = na.rm, ...) |
| 17 | 39x |
discard_message(x, keep = !i, margin = margin, verbose = verbose) |
| 18 | 19x |
if (any(margin == 1)) return(x[!i, , drop = FALSE]) |
| 19 | 20x |
if (any(margin == 2)) return(x[, !i, drop = FALSE]) |
| 20 | ! |
i |
| 21 |
} |
|
| 22 |
) |
|
| 23 | ||
| 24 |
#' @export |
|
| 25 |
#' @rdname discard |
|
| 26 |
#' @aliases discard_rows,ANY-method |
|
| 27 |
setMethod( |
|
| 28 |
f = "discard_rows", |
|
| 29 |
signature = c(x = "ANY"), |
|
| 30 |
definition = function(x, f, negate = FALSE, all = FALSE, na.rm = FALSE, |
|
| 31 |
verbose = getOption("arkhe.verbose"), ...) {
|
|
| 32 | 4x |
discard(x, f, margin = 1, negate = negate, all = all, na.rm = na.rm, |
| 33 | 4x |
verbose = verbose, ...) |
| 34 |
} |
|
| 35 |
) |
|
| 36 | ||
| 37 |
#' @export |
|
| 38 |
#' @rdname discard |
|
| 39 |
#' @aliases discard_columns,ANY-method |
|
| 40 |
setMethod( |
|
| 41 |
f = "discard_columns", |
|
| 42 |
signature = c(x = "ANY"), |
|
| 43 |
definition = function(x, f, negate = FALSE, all = FALSE, na.rm = FALSE, |
|
| 44 |
verbose = getOption("arkhe.verbose"), ...) {
|
|
| 45 | 4x |
discard(x, f, margin = 2, negate = negate, all = all, na.rm = na.rm, |
| 46 | 4x |
verbose = verbose, ...) |
| 47 |
} |
|
| 48 |
) |
|
| 49 | ||
| 50 |
#' Diagnostic Message |
|
| 51 |
#' |
|
| 52 |
#' Generates a diagnostic message describing columns or rows that are being |
|
| 53 |
#' removed. |
|
| 54 |
#' @param x A [`matrix`] or a [`data.frame`]. |
|
| 55 |
#' @param margin A length-one [`numeric`] vector giving the subscripts which the |
|
| 56 |
#' function will be applied over (`1` indicates rows, `2` indicates columns). |
|
| 57 |
#' @param keep A [`logical`] vector of rows or columns to keep (`TRUE`) or |
|
| 58 |
#' remove (`FALSE`). |
|
| 59 |
#' @param verbose A [`logical`] scalar: should the message be generated? |
|
| 60 |
#' @keywords internal |
|
| 61 |
#' @noRd |
|
| 62 |
discard_message <- function(x, keep, margin, |
|
| 63 |
verbose = getOption("arkhe.verbose")) {
|
|
| 64 | 49x |
drop <- sum(!keep, na.rm = TRUE) |
| 65 | 49x |
what <- ngettext(drop, "element", "elements") |
| 66 | 24x |
if (any(margin == 1)) what <- ngettext(drop, "row", "rows") |
| 67 | 25x |
if (any(margin == 2)) what <- ngettext(drop, "column", "columns") |
| 68 | ||
| 69 | 49x |
if (drop == 0) {
|
| 70 | 21x |
msg <- tr_("Nothing to remove.")
|
| 71 |
} else {
|
|
| 72 | 28x |
pc <- sprintf("%0.3g%%", 100 * drop / length(keep))
|
| 73 | 28x |
if (margin == 2 && !is.null(colnames(x))) {
|
| 74 | 6x |
pc <- paste0(colnames(x)[!keep], collapse = ", ") |
| 75 |
} |
|
| 76 | 28x |
msg <- tr_("Removing %g %s out of %g (%s).")
|
| 77 | 28x |
msg <- sprintf(msg, drop, what, length(keep), pc) |
| 78 |
} |
|
| 79 | ||
| 80 | 8x |
if (isTRUE(verbose)) message(msg) |
| 81 | 49x |
invisible(msg) |
| 82 |
} |
| 1 |
# DATA CLEANING: ASSIGN |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
#' @export |
|
| 6 |
#' @rdname assign |
|
| 7 |
#' @aliases assign_rownames,data.frame-method |
|
| 8 |
setMethod( |
|
| 9 |
f = "assign_rownames", |
|
| 10 |
signature = c(x = "data.frame"), |
|
| 11 |
definition = function(x, column, remove = TRUE) {
|
|
| 12 |
## Validation |
|
| 13 | 1x |
assert_length(column, 1) |
| 14 | ! |
if ((column > ncol(x)) | (column < 1)) return(x) |
| 15 | ||
| 16 | 1x |
y <- x |
| 17 | 1x |
rownames(y) <- y[, column] |
| 18 | 1x |
if (remove) {
|
| 19 | 1x |
y <- y[, -column, drop = FALSE] |
| 20 |
} |
|
| 21 | 1x |
y |
| 22 |
} |
|
| 23 |
) |
|
| 24 | ||
| 25 |
#' @export |
|
| 26 |
#' @rdname assign |
|
| 27 |
#' @aliases assign_colnames,data.frame-method |
|
| 28 |
setMethod( |
|
| 29 |
f = "assign_colnames", |
|
| 30 |
signature = c(x = "data.frame"), |
|
| 31 |
definition = function(x, row, remove = TRUE) {
|
|
| 32 |
## Validation |
|
| 33 | 1x |
assert_length(row, 1) |
| 34 | ! |
if ((row > nrow(x)) | (row < 1)) return(x) |
| 35 | ||
| 36 | 1x |
y <- x |
| 37 | 1x |
colnames(y) <- y[row, ] |
| 38 | 1x |
if (remove) {
|
| 39 | 1x |
y <- y[-row, , drop = FALSE] |
| 40 |
} |
|
| 41 | 1x |
y |
| 42 |
} |
|
| 43 |
) |
| 1 |
# HELPERS |
|
| 2 | ||
| 3 |
## https://michaelchirico.github.io/potools/articles/developers.html |
|
| 4 |
tr_ <- function(...) {
|
|
| 5 | 309x |
enc2utf8(gettext(paste0(...), domain = "R-arkhe")) |
| 6 |
} |
|
| 7 | ||
| 8 |
## https://stackoverflow.com/questions/56191862/where-do-i-specify-random-seed-for-tests-in-r-package |
|
| 9 |
#' Evaluate an Expression with a Temporarily Seed |
|
| 10 |
#' |
|
| 11 |
#' @param expr An [`expression`] to be evaluated. |
|
| 12 |
#' @param seed A single value to be passed to [set.seed()]. |
|
| 13 |
#' @param envir The [environment][environment()] in which `expr` should be |
|
| 14 |
#' evaluated. |
|
| 15 |
#' @param rounding A [`logical`] scalar: should the default discrete uniform |
|
| 16 |
#' generation method in \R versions prior to 3.6.0 be used? Usefull for unit |
|
| 17 |
#' testing. |
|
| 18 |
#' @param ... Further arguments to be passed to [set.seed()]. |
|
| 19 |
#' @return |
|
| 20 |
#' The results of `expr` evaluated. |
|
| 21 |
#' @seealso [set.seed()] |
|
| 22 |
#' @keywords internal |
|
| 23 |
with_seed <- function(expr, seed, ..., envir = parent.frame(), rounding = TRUE) {
|
|
| 24 | 3x |
expr <- substitute(expr) |
| 25 |
## Save and restore the random number generator (RNG) state |
|
| 26 | 3x |
env <- globalenv() |
| 27 | 3x |
old_seed <- env$.Random.seed |
| 28 | 3x |
on.exit({
|
| 29 | 3x |
if (is.null(old_seed)) {
|
| 30 | ! |
rm(list = ".Random.seed", envir = env, inherits = FALSE) |
| 31 |
} else {
|
|
| 32 | 3x |
assign(".Random.seed", value = old_seed, envir = env, inherits = FALSE)
|
| 33 |
} |
|
| 34 |
}) |
|
| 35 |
## Keep the results the same for R versions prior to 3.6 |
|
| 36 | 3x |
if (isTRUE(rounding) && getRversion() >= "3.6") {
|
| 37 |
## Set sample.kind = "Rounding" to reproduce the old sampling |
|
| 38 |
## Suppress warning "non-uniform 'Rounding' sampler used" |
|
| 39 | 3x |
suppressWarnings(set.seed(seed, sample.kind = "Rounding")) |
| 40 |
} else {
|
|
| 41 | ! |
set.seed(seed) |
| 42 |
} |
|
| 43 | 3x |
eval(expr, envir = envir) |
| 44 |
} |
| 1 |
# SEEK |
|
| 2 | ||
| 3 |
seek <- function(x, margin = 2, select = NULL, names = NULL, ...) {
|
|
| 4 | 16x |
assert_filled(x) |
| 5 | 16x |
assert_length(margin, 1) |
| 6 | 16x |
assert_type(names, "character", allow_null = TRUE) |
| 7 | ||
| 8 | 14x |
dm <- dim(x)[[margin]] |
| 9 | 14x |
nm <- dimnames(x)[[margin]] |
| 10 | ! |
if (is.null(nm)) return(NULL) |
| 11 | ||
| 12 | 14x |
if (is.null(select)) {
|
| 13 | 2x |
if (is.null(names)) return(NULL) |
| 14 | 4x |
select <- function(i) match(names, i) |
| 15 |
} |
|
| 16 | ||
| 17 | 12x |
assert_function(select) |
| 18 | 12x |
i <- select(nm, ...) |
| 19 | ||
| 20 | 8x |
if (is.logical(i)) i <- which(i) |
| 21 | 4x |
if (length(i) == 0 || all(is.na(i))) i <- NULL |
| 22 | 12x |
assert_type(i, "integer", allow_null = TRUE) |
| 23 | 12x |
i |
| 24 |
} |
|
| 25 | ||
| 26 |
#' @export |
|
| 27 |
#' @rdname seek |
|
| 28 |
#' @aliases seek_rows,data.frame-method |
|
| 29 |
setMethod( |
|
| 30 |
f = "seek_rows", |
|
| 31 |
signature = c(x = "data.frame"), |
|
| 32 |
definition = function(x, select = NULL, names = NULL, ...) {
|
|
| 33 | 7x |
seek(x, margin = 1, select = select, names = names, ...) |
| 34 |
} |
|
| 35 |
) |
|
| 36 | ||
| 37 |
#' @export |
|
| 38 |
#' @rdname seek |
|
| 39 |
#' @aliases seek_rows,matrix-method |
|
| 40 |
setMethod( |
|
| 41 |
f = "seek_rows", |
|
| 42 |
signature = c(x = "matrix"), |
|
| 43 |
definition = function(x, select = NULL, names = NULL, ...) {
|
|
| 44 | 1x |
seek(x, margin = 1, select = select, names = names, ...) |
| 45 |
} |
|
| 46 |
) |
|
| 47 | ||
| 48 |
#' @export |
|
| 49 |
#' @rdname seek |
|
| 50 |
#' @aliases seek_columns,data.frame-method |
|
| 51 |
setMethod( |
|
| 52 |
f = "seek_columns", |
|
| 53 |
signature = c(x = "data.frame"), |
|
| 54 |
definition = function(x, select = NULL, names = NULL, ...) {
|
|
| 55 | 7x |
seek(x, margin = 2, select = select, names = names, ...) |
| 56 |
} |
|
| 57 |
) |
|
| 58 | ||
| 59 |
#' @export |
|
| 60 |
#' @rdname seek |
|
| 61 |
#' @aliases seek_columns,matrix-method |
|
| 62 |
setMethod( |
|
| 63 |
f = "seek_columns", |
|
| 64 |
signature = c(x = "matrix"), |
|
| 65 |
definition = function(x, select = NULL, names = NULL, ...) {
|
|
| 66 | 1x |
seek(x, margin = 2, select = select, names = names, ...) |
| 67 |
} |
|
| 68 |
) |
| 1 |
# DATA CLEANING: KEEP |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# keep ========================================================================= |
|
| 6 |
#' @export |
|
| 7 |
#' @rdname keep |
|
| 8 |
#' @aliases keep,ANY-method |
|
| 9 |
setMethod( |
|
| 10 |
f = "keep", |
|
| 11 |
signature = c(x = "ANY"), |
|
| 12 |
definition = function(x, f, margin = 1, negate = FALSE, all = FALSE, |
|
| 13 |
na.rm = FALSE, verbose = getOption("arkhe.verbose"),
|
|
| 14 |
...) {
|
|
| 15 | 10x |
i <- detect(x, f = f, margin = margin, negate = negate, all = all, |
| 16 | 10x |
na.rm = na.rm, ...) |
| 17 | 10x |
discard_message(x, keep = i, margin = margin, verbose = verbose) |
| 18 | 5x |
if (any(margin == 1)) return(x[i, , drop = FALSE]) |
| 19 | 5x |
if (any(margin == 2)) return(x[, i, drop = FALSE]) |
| 20 | ! |
i |
| 21 |
} |
|
| 22 |
) |
|
| 23 | ||
| 24 |
#' @export |
|
| 25 |
#' @rdname keep |
|
| 26 |
#' @aliases keep_rows,ANY-method |
|
| 27 |
setMethod( |
|
| 28 |
f = "keep_rows", |
|
| 29 |
signature = c(x = "ANY"), |
|
| 30 |
definition = function(x, f, negate = FALSE, all = FALSE, na.rm = FALSE, |
|
| 31 |
verbose = getOption("arkhe.verbose"), ...) {
|
|
| 32 | 5x |
keep(x, f, margin = 1, negate = negate, all = all, na.rm = na.rm, |
| 33 | 5x |
verbose = verbose, ...) |
| 34 |
} |
|
| 35 |
) |
|
| 36 | ||
| 37 |
#' @export |
|
| 38 |
#' @rdname keep |
|
| 39 |
#' @aliases keep_columns,ANY-method |
|
| 40 |
setMethod( |
|
| 41 |
f = "keep_columns", |
|
| 42 |
signature = c(x = "ANY"), |
|
| 43 |
definition = function(x, f, negate = FALSE, all = FALSE, na.rm = FALSE, |
|
| 44 |
verbose = getOption("arkhe.verbose"), ...) {
|
|
| 45 | 5x |
keep(x, f, margin = 2, negate = negate, all = all, na.rm = na.rm, |
| 46 | 5x |
verbose = verbose, ...) |
| 47 |
} |
|
| 48 |
) |
| 1 |
# DATA CLEANING: COUNT |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# Count ======================================================================== |
|
| 6 |
#' @export |
|
| 7 |
#' @rdname count |
|
| 8 |
#' @aliases count,data.frame-method |
|
| 9 |
setMethod( |
|
| 10 |
f = "count", |
|
| 11 |
signature = c(x = "data.frame"), |
|
| 12 |
definition = function(x, f, margin = 1, negate = FALSE, na.rm = FALSE, ...) {
|
|
| 13 | 42x |
assert_function(f) |
| 14 | 6x |
if (negate) f <- Negate(f) |
| 15 | 42x |
x[] <- lapply(X = x, FUN = f, ...) |
| 16 | 16x |
if (any(margin == 1)) return(rowSums(x, na.rm = na.rm)) |
| 17 | 25x |
if (any(margin == 2)) return(colSums(x, na.rm = na.rm)) |
| 18 | 1x |
x |
| 19 |
} |
|
| 20 |
) |
|
| 21 | ||
| 22 |
#' @export |
|
| 23 |
#' @rdname count |
|
| 24 |
#' @aliases count,matrix-method |
|
| 25 |
setMethod( |
|
| 26 |
f = "count", |
|
| 27 |
signature = c(x = "matrix"), |
|
| 28 |
definition = function(x, f, margin = 1, negate = FALSE, na.rm = FALSE, ...) {
|
|
| 29 | 36x |
assert_function(f) |
| 30 | 2x |
if (negate) f <- Negate(f) |
| 31 | 36x |
x <- apply(X = x, MARGIN = margin, FUN = f, ..., simplify = TRUE) |
| 32 |
## If simplify is TRUE: |
|
| 33 |
## apply() returns an array of dimension c(n, dim(X)[MARGIN]) if n > 1 |
|
| 34 |
## apply() returns a vector if n == 1 and MARGIN has length 1 |
|
| 35 | ! |
if (is.null(dim(x))) x <- matrix(x, nrow = 1) |
| 36 | 36x |
colSums(x, na.rm = na.rm) |
| 37 |
} |
|
| 38 |
) |
| 1 |
# DATA CLEANING: DETECT |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# Detect ======================================================================= |
|
| 6 |
#' @export |
|
| 7 |
#' @rdname detect |
|
| 8 |
#' @aliases detect,ANY-method |
|
| 9 |
setMethod( |
|
| 10 |
f = "detect", |
|
| 11 |
signature = c(x = "ANY"), |
|
| 12 |
definition = function(x, f, margin = 1, negate = FALSE, all = FALSE, |
|
| 13 |
na.rm = FALSE, ...) {
|
|
| 14 | 59x |
total <- count(x, f, margin = margin, negate = negate, na.rm = na.rm, ...) |
| 15 | ||
| 16 | 59x |
miss <- rep(0, length(total)) |
| 17 | 10x |
if (na.rm) miss <- count(x, f = is.na, margin = margin) |
| 18 | ||
| 19 | 59x |
k <- 1 |
| 20 | 59x |
if (all) {
|
| 21 | 15x |
if (any(margin == 1)) k <- ncol(x) - miss |
| 22 | 18x |
if (any(margin == 2)) k <- nrow(x) - miss |
| 23 |
} |
|
| 24 | 59x |
total >= k |
| 25 |
} |
|
| 26 |
) |
| 1 |
# DATA CLEANING: REPLACE |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# Replace ====================================================================== |
|
| 6 |
## Missing values -------------------------------------------------------------- |
|
| 7 |
#' @export |
|
| 8 |
#' @rdname replace_NA |
|
| 9 |
#' @aliases replace_NA,matrix-method |
|
| 10 |
setMethod( |
|
| 11 |
f = "replace_NA", |
|
| 12 |
signature = c(x = "matrix"), |
|
| 13 |
definition = function(x, value = 0) {
|
|
| 14 | 1x |
x[is.na(x)] <- value |
| 15 | 1x |
x |
| 16 |
} |
|
| 17 |
) |
|
| 18 | ||
| 19 |
#' @export |
|
| 20 |
#' @rdname replace_NA |
|
| 21 |
#' @aliases replace_NA,data.frame-method |
|
| 22 |
setMethod( |
|
| 23 |
f = "replace_NA", |
|
| 24 |
signature = c(x = "data.frame"), |
|
| 25 |
definition = function(x, value = 0) {
|
|
| 26 | 1x |
x[] <- lapply( |
| 27 | 1x |
X = x, |
| 28 | 1x |
FUN = function(x, value) {
|
| 29 | 3x |
x[is.na(x)] <- value |
| 30 | 3x |
x |
| 31 |
}, |
|
| 32 | 1x |
value = value |
| 33 |
) |
|
| 34 | 1x |
x |
| 35 |
} |
|
| 36 |
) |
|
| 37 | ||
| 38 |
## Infinite values ------------------------------------------------------------- |
|
| 39 |
#' @export |
|
| 40 |
#' @rdname replace_Inf |
|
| 41 |
#' @aliases replace_Inf,matrix-method |
|
| 42 |
setMethod( |
|
| 43 |
f = "replace_Inf", |
|
| 44 |
signature = c(x = "matrix"), |
|
| 45 |
definition = function(x, value = 0) {
|
|
| 46 | 1x |
x[is.infinite(x)] <- value |
| 47 | 1x |
x |
| 48 |
} |
|
| 49 |
) |
|
| 50 | ||
| 51 |
#' @export |
|
| 52 |
#' @rdname replace_Inf |
|
| 53 |
#' @aliases replace_Inf,data.frame-method |
|
| 54 |
setMethod( |
|
| 55 |
f = "replace_Inf", |
|
| 56 |
signature = c(x = "data.frame"), |
|
| 57 |
definition = function(x, value = 0) {
|
|
| 58 | 1x |
x[] <- lapply( |
| 59 | 1x |
X = x, |
| 60 | 1x |
FUN = function(x, value) {
|
| 61 | 3x |
x[is.infinite(x)] <- value |
| 62 | 3x |
x |
| 63 |
}, |
|
| 64 | 1x |
value = value |
| 65 |
) |
|
| 66 | 1x |
x |
| 67 |
} |
|
| 68 |
) |
|
| 69 | ||
| 70 |
## Zeros ----------------------------------------------------------------------- |
|
| 71 |
#' @export |
|
| 72 |
#' @rdname replace_zero |
|
| 73 |
#' @aliases replace_zero,matrix-method |
|
| 74 |
setMethod( |
|
| 75 |
f = "replace_zero", |
|
| 76 |
signature = c(x = "matrix"), |
|
| 77 |
definition = function(x, value) {
|
|
| 78 | 1x |
x[is_zero(x)] <- value |
| 79 | 1x |
x |
| 80 |
} |
|
| 81 |
) |
|
| 82 | ||
| 83 |
#' @export |
|
| 84 |
#' @rdname replace_zero |
|
| 85 |
#' @aliases replace_zero,data.frame-method |
|
| 86 |
setMethod( |
|
| 87 |
f = "replace_zero", |
|
| 88 |
signature = c(x = "data.frame"), |
|
| 89 |
definition = function(x, value) {
|
|
| 90 | 1x |
num <- vapply(X = x, FUN = is.numeric, FUN.VALUE = logical(1)) |
| 91 | 1x |
nozero <- lapply( |
| 92 | 1x |
X = x[, num, drop = FALSE], |
| 93 | 1x |
FUN = function(x, value) {
|
| 94 | 2x |
x[is_zero(x)] <- value |
| 95 | 2x |
x |
| 96 |
}, |
|
| 97 | 1x |
value = value |
| 98 |
) |
|
| 99 | 1x |
x[, num] <- nozero |
| 100 | 1x |
x |
| 101 |
} |
|
| 102 |
) |
|
| 103 | ||
| 104 |
## Empty string ---------------------------------------------------------------- |
|
| 105 |
#' @export |
|
| 106 |
#' @rdname replace_empty |
|
| 107 |
#' @aliases replace_empty,matrix-method |
|
| 108 |
setMethod( |
|
| 109 |
f = "replace_empty", |
|
| 110 |
signature = c(x = "matrix"), |
|
| 111 |
definition = function(x, value) {
|
|
| 112 | 1x |
x[!nzchar(x)] <- value |
| 113 | 1x |
x |
| 114 |
} |
|
| 115 |
) |
|
| 116 | ||
| 117 |
#' @export |
|
| 118 |
#' @rdname replace_empty |
|
| 119 |
#' @aliases replace_empty,data.frame-method |
|
| 120 |
setMethod( |
|
| 121 |
f = "replace_empty", |
|
| 122 |
signature = c(x = "data.frame"), |
|
| 123 |
definition = function(x, value) {
|
|
| 124 | 1x |
char <- vapply(X = x, FUN = is.character, FUN.VALUE = logical(1)) |
| 125 | 1x |
noblank <- lapply( |
| 126 | 1x |
X = x[, char, drop = FALSE], |
| 127 | 1x |
FUN = function(x, value) {
|
| 128 | 1x |
x[!nzchar(x)] <- value |
| 129 | 1x |
x |
| 130 |
}, |
|
| 131 | 1x |
value = value |
| 132 |
) |
|
| 133 | 1x |
x[, char] <- noblank |
| 134 | 1x |
x |
| 135 |
} |
|
| 136 |
) |
| 1 |
# CONDITIONS |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
#' Conditions |
|
| 6 |
#' |
|
| 7 |
#' * `throw_error()` stops execution of the current expression and executes an |
|
| 8 |
#' error action. |
|
| 9 |
#' * `throw_warning()` generates a warning message. |
|
| 10 |
#' * `catch_conditions()` and `catch_message()` handles unusual conditions. |
|
| 11 |
#' @param expr An expression to be evaluated. |
|
| 12 |
#' @param .subclass A [`character`] string specifying the class of |
|
| 13 |
#' the message to be returned. |
|
| 14 |
#' @param message A [`character`] string specifying the message to be |
|
| 15 |
#' returned. |
|
| 16 |
#' @param call The call. |
|
| 17 |
#' @param ... Extra arguments. |
|
| 18 |
#' @author N. Frerebeau |
|
| 19 |
#' @name conditions |
|
| 20 |
#' @rdname conditions |
|
| 21 |
#' @family condition |
|
| 22 |
#' @keywords internal error |
|
| 23 |
NULL |
|
| 24 | ||
| 25 |
#' @rdname conditions |
|
| 26 |
throw_error <- function(.subclass, message, call = NULL, ...) {
|
|
| 27 | 52x |
err <- structure( |
| 28 | 52x |
list( |
| 29 | 52x |
message = message, |
| 30 | 52x |
call = call, |
| 31 |
... |
|
| 32 |
), |
|
| 33 | 52x |
class = c(.subclass, "error", "condition") |
| 34 |
) |
|
| 35 | 52x |
stop(err) |
| 36 |
} |
|
| 37 | ||
| 38 |
#' @rdname conditions |
|
| 39 |
throw_warning <- function(.subclass, message, call = NULL, ...) {
|
|
| 40 | ! |
wrn <- structure( |
| 41 | ! |
list( |
| 42 | ! |
message = message, |
| 43 | ! |
call = call, |
| 44 |
... |
|
| 45 |
), |
|
| 46 | ! |
class = c(.subclass, "warning", "condition") |
| 47 |
) |
|
| 48 | ! |
warning(wrn) |
| 49 |
} |
|
| 50 | ||
| 51 |
#' @rdname conditions |
|
| 52 |
catch_message <- function(expr) {
|
|
| 53 | 6x |
cnd <- vector(mode = "character") |
| 54 | 6x |
add_msg <- function(x) {
|
| 55 | 1x |
cnd <<- append(cnd, x$message) |
| 56 | 1x |
invokeRestart("muffleMessage")
|
| 57 |
} |
|
| 58 | 6x |
add_wrn <- function(x) {
|
| 59 | 3x |
cnd <<- append(cnd, x$message) |
| 60 | 3x |
invokeRestart("muffleWarning")
|
| 61 |
} |
|
| 62 | 6x |
add_err <- function(x) {
|
| 63 | 1x |
cnd <<- append(cnd, x$message) |
| 64 |
} |
|
| 65 | ||
| 66 | 6x |
tryCatch( |
| 67 | 6x |
error = add_err, |
| 68 | 6x |
withCallingHandlers( |
| 69 | 6x |
message = add_msg, |
| 70 | 6x |
warning = add_wrn, |
| 71 | 6x |
expr |
| 72 |
) |
|
| 73 |
) |
|
| 74 | 6x |
return(cnd) |
| 75 |
} |
|
| 76 | ||
| 77 |
#' @rdname conditions |
|
| 78 |
catch_conditions <- function(expr) {
|
|
| 79 | 46x |
cnd <- vector(mode = "list") |
| 80 | 46x |
add_msg <- function(x) {
|
| 81 | 2x |
cnd <<- append(cnd, list(x)) |
| 82 | 2x |
invokeRestart("muffleMessage")
|
| 83 |
} |
|
| 84 | 46x |
add_wrn <- function(x) {
|
| 85 | 1x |
cnd <<- append(cnd, list(x)) |
| 86 | 1x |
invokeRestart("muffleWarning")
|
| 87 |
} |
|
| 88 | 46x |
add_err <- function(x) {
|
| 89 | 43x |
cnd <<- append(cnd, list(x)) |
| 90 |
} |
|
| 91 | ||
| 92 | 46x |
tryCatch( |
| 93 | 46x |
error = add_err, |
| 94 | 46x |
withCallingHandlers( |
| 95 | 46x |
message = add_msg, |
| 96 | 46x |
warning = add_wrn, |
| 97 | 46x |
expr |
| 98 |
) |
|
| 99 |
) |
|
| 100 | 46x |
return(cnd) |
| 101 |
} |
|
| 102 | ||
| 103 |
# Diagnostic =================================================================== |
|
| 104 |
#' Class Diagnostic |
|
| 105 |
#' |
|
| 106 |
#' @param object An object to which error messages are related. |
|
| 107 |
#' @param conditions A [`list`] of condition messages. |
|
| 108 |
#' @return |
|
| 109 |
#' Throw an error if `conditions` is of non-zero length, invisibly returns |
|
| 110 |
#' `TRUE` if not. |
|
| 111 |
#' @author N. Frerebeau |
|
| 112 |
#' @keywords internal |
|
| 113 |
#' @export |
|
| 114 |
check_class <- function(object, conditions) {
|
|
| 115 | ! |
cnd <- Filter(Negate(is_empty), conditions) |
| 116 | ! |
if (has_length(cnd)) {
|
| 117 | ! |
li <- paste0("* ", cnd, collapse = "\n")
|
| 118 | ! |
err <- sprintf(tr_("<%s> instance initialization:\n%s"), class(object), li)
|
| 119 | ! |
throw_error("arkhe_error_class", err, call = NULL)
|
| 120 |
} |
|
| 121 | ||
| 122 | ! |
invisible(TRUE) |
| 123 |
} |
| 1 |
# MATHEMATICS |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
#' @export |
|
| 6 |
#' @rdname math_gcd |
|
| 7 |
#' @aliases math_gcd,numeric,numeric-method |
|
| 8 |
setMethod( |
|
| 9 |
f = "math_gcd", |
|
| 10 |
signature = c(x = "numeric", y = "numeric"), |
|
| 11 |
definition = function(x, y) {
|
|
| 12 | 12x |
mapply( |
| 13 | 12x |
FUN = function(a, b) {
|
| 14 | 4x |
if (isTRUE(all.equal(b, 0))) return(a) |
| 15 | 10x |
math_gcd(b, a %% b) |
| 16 |
}, |
|
| 17 | 12x |
a = x, |
| 18 | 12x |
b = y |
| 19 |
) |
|
| 20 |
} |
|
| 21 |
) |
|
| 22 | ||
| 23 |
#' @export |
|
| 24 |
#' @rdname math_lcm |
|
| 25 |
#' @aliases math_lcm,numeric,numeric-method |
|
| 26 |
setMethod( |
|
| 27 |
f = "math_lcm", |
|
| 28 |
signature = c(x = "numeric", y = "numeric"), |
|
| 29 |
definition = function(x, y) {
|
|
| 30 | 1x |
(x * y) / math_gcd(x, y) |
| 31 |
} |
|
| 32 |
) |
| 1 |
# UTILITIES |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
#' Default value for NULL |
|
| 6 |
#' |
|
| 7 |
#' Replaces `NULL` with a default value. |
|
| 8 |
#' @param x,y An object. |
|
| 9 |
#' @return If `x` is `NULL`, returns `y`; otherwise returns `x`. |
|
| 10 |
#' @family utilities |
|
| 11 |
#' @keywords utilities |
|
| 12 |
#' @name null |
|
| 13 |
#' @rdname null |
|
| 14 |
#' @export |
|
| 15 |
`%||%` <- function(x, y) {
|
|
| 16 |
if (is.null(x)) y else x |
|
| 17 |
} |
|
| 18 | ||
| 19 |
# Reexport from base on newer versions of R to avoid conflict messages |
|
| 20 |
if (exists("%||%", envir = baseenv())) {
|
|
| 21 |
`%||%` <- get("%||%", envir = baseenv())
|
|
| 22 |
} |
|
| 23 | ||
| 24 |
#' Concatenate |
|
| 25 |
#' |
|
| 26 |
#' Concatenates character vectors. |
|
| 27 |
#' @param x,y A [`character`] vector. |
|
| 28 |
#' @return A [`character`] vector. |
|
| 29 |
#' @family utilities |
|
| 30 |
#' @keywords utilities |
|
| 31 |
#' @name concat |
|
| 32 |
#' @rdname concat |
|
| 33 |
#' @export |
|
| 34 |
`%+%` <- function (x, y) {
|
|
| 35 | 4x |
stopifnot(is.character(x), is.character(y)) |
| 36 | 4x |
stopifnot(length(x) == length(y) || length(x) == 1 || length(y) == 1) |
| 37 | ||
| 38 | 1x |
if (length(x) == 0 && length(y) == 0) paste0(x, y) |
| 39 | 1x |
else if (length(x) == 0) x |
| 40 | 1x |
else if (length(y) == 0) y |
| 41 | 1x |
else paste0(x, y) |
| 42 |
} |
| 1 |
# DATA CLEANING: REMOVE |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# Missing values =============================================================== |
|
| 6 |
#' @export |
|
| 7 |
#' @rdname remove_NA |
|
| 8 |
#' @aliases remove_NA,ANY-method |
|
| 9 |
setMethod( |
|
| 10 |
f = "remove_NA", |
|
| 11 |
signature = c(x = "ANY"), |
|
| 12 |
definition = function(x, margin = 1, all = FALSE, |
|
| 13 |
verbose = getOption("arkhe.verbose")) {
|
|
| 14 | 4x |
discard(x, f = is.na, margin = margin, all = all, verbose = verbose) |
| 15 |
} |
|
| 16 |
) |
|
| 17 | ||
| 18 |
# Infinite values ============================================================== |
|
| 19 |
#' @export |
|
| 20 |
#' @rdname remove_Inf |
|
| 21 |
#' @aliases remove_Inf,ANY-method |
|
| 22 |
setMethod( |
|
| 23 |
f = "remove_Inf", |
|
| 24 |
signature = c(x = "ANY"), |
|
| 25 |
definition = function(x, margin = 1, all = FALSE, |
|
| 26 |
verbose = getOption("arkhe.verbose")) {
|
|
| 27 | 4x |
discard(x, f = is.infinite, margin = margin, all = all, verbose = verbose) |
| 28 |
} |
|
| 29 |
) |
|
| 30 | ||
| 31 |
# Zeros ======================================================================== |
|
| 32 |
#' @export |
|
| 33 |
#' @rdname remove_zero |
|
| 34 |
#' @aliases remove_zero,ANY-method |
|
| 35 |
setMethod( |
|
| 36 |
f = "remove_zero", |
|
| 37 |
signature = c(x = "ANY"), |
|
| 38 |
definition = function(x, margin = 1, all = FALSE, |
|
| 39 |
verbose = getOption("arkhe.verbose")) {
|
|
| 40 | 4x |
discard(x, f = is_zero_numeric, margin = margin, |
| 41 | 4x |
all = all, na.rm = TRUE, verbose = verbose) |
| 42 |
} |
|
| 43 |
) |
|
| 44 | ||
| 45 |
# Empty string ================================================================= |
|
| 46 |
#' @export |
|
| 47 |
#' @rdname remove_empty |
|
| 48 |
#' @aliases remove_empty,ANY-method |
|
| 49 |
setMethod( |
|
| 50 |
f = "remove_empty", |
|
| 51 |
signature = c(x = "ANY"), |
|
| 52 |
definition = function(x, margin = 1, all = FALSE, |
|
| 53 |
verbose = getOption("arkhe.verbose")) {
|
|
| 54 | 4x |
discard(x, f = nzchar, margin = margin, negate = TRUE, |
| 55 | 4x |
all = all, na.rm = TRUE, verbose = verbose) |
| 56 |
} |
|
| 57 |
) |
|
| 58 | ||
| 59 |
# Constant ===================================================================== |
|
| 60 |
#' @export |
|
| 61 |
#' @rdname remove_constant |
|
| 62 |
#' @aliases remove_constant,ANY-method |
|
| 63 |
setMethod( |
|
| 64 |
f = "remove_constant", |
|
| 65 |
signature = c(x = "ANY"), |
|
| 66 |
definition = function(x, na.rm = FALSE, verbose = getOption("arkhe.verbose")) {
|
|
| 67 | 6x |
discard(x, f = function(x) { is_unique(x, na.rm = na.rm) },
|
| 68 | 3x |
margin = 2, all = FALSE, verbose = verbose) |
| 69 |
} |
|
| 70 |
) |
| 1 |
# DATA TRANSFORMATION |
|
| 2 |
NULL |
|
| 3 | ||
| 4 |
#' Rescale Continuous Vector (minimum, maximum) |
|
| 5 |
#' |
|
| 6 |
#' Rescales continuous vector to have specified minimum and maximum. |
|
| 7 |
#' @param x A [`numeric`] vector. |
|
| 8 |
#' @param to A length-two [`numeric`] vector specifying the output range. |
|
| 9 |
#' @param from A length-two [`numeric`] vector specifying the input range. |
|
| 10 |
#' @return A [`numeric`] vector. |
|
| 11 |
#' @note For internal use only. |
|
| 12 |
#' @family scales |
|
| 13 |
#' @export |
|
| 14 |
scale_range <- function(x, to = c(0, 1), from = range(x, finite = TRUE)) {
|
|
| 15 | ! |
if (.is_zero(to) || .is_zero(from)) return(ifelse(is.na(x), NA, mean(to))) |
| 16 | 1x |
(x - from[1L]) / diff(from) * diff(to) + to[1L] |
| 17 |
} |
|
| 18 | ||
| 19 |
#' Rescale Continuous Vector (minimum, midpoint, maximum) |
|
| 20 |
#' |
|
| 21 |
#' Rescales continuous vector to have specified minimum, midpoint and maximum. |
|
| 22 |
#' @param x A [`numeric`] vector. |
|
| 23 |
#' @param to A length-two [`numeric`] vector specifying the output range. |
|
| 24 |
#' @param from A length-two [`numeric`] vector specifying the input range. |
|
| 25 |
#' @param midpoint A length-one [`numeric`] vector specifying the mid-point of |
|
| 26 |
#' input range. |
|
| 27 |
#' @return A [`numeric`] vector. |
|
| 28 |
#' @note For internal use only. |
|
| 29 |
#' @family scales |
|
| 30 |
#' @export |
|
| 31 |
scale_midpoint <- function(x, to = c(0, 1), from = range(x, finite = TRUE), midpoint = 0) {
|
|
| 32 | ! |
if (.is_zero(to) || .is_zero(from)) return(ifelse(is.na(x), NA, mean(to))) |
| 33 | 1x |
extent <- 2 * max(abs(from - midpoint)) |
| 34 | 1x |
(x - midpoint) / extent * diff(to) + mean(to) |
| 35 |
} |
|
| 36 | ||
| 37 |
.is_zero <- function(x, tolerance = sqrt(.Machine$double.eps)) {
|
|
| 38 | 4x |
diff(range(x)) <= tolerance |
| 39 |
} |
| 1 |
# DATA CLEANING: COMPACT |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
## compact rows/columns ======================================================== |
|
| 6 |
#' @export |
|
| 7 |
#' @rdname compact |
|
| 8 |
#' @aliases compact,ANY-method |
|
| 9 |
setMethod( |
|
| 10 |
f = "compact", |
|
| 11 |
signature = c(x = "ANY"), |
|
| 12 |
definition = function(x, margin = 1, na.rm = FALSE, |
|
| 13 |
verbose = getOption("arkhe.verbose")) {
|
|
| 14 | 12x |
vide <- function(x) {
|
| 15 | 13x |
if (is_numeric(x)) x == 0 |
| 16 | 24x |
else if (is_logical(x)) !x |
| 17 | 13x |
else if (is_character(x)) x == "" |
| 18 | ! |
else rep(FALSE, length(x)) |
| 19 |
} |
|
| 20 | 12x |
discard(x, f = vide, margin = margin, all = TRUE, |
| 21 | 12x |
na.rm = na.rm, verbose = verbose) |
| 22 |
} |
|
| 23 |
) |
|
| 24 | ||
| 25 |
#' @export |
|
| 26 |
#' @rdname compact |
|
| 27 |
#' @aliases compact_columns,ANY-method |
|
| 28 |
setMethod( |
|
| 29 |
f = "compact_columns", |
|
| 30 |
signature = c(x = "ANY"), |
|
| 31 |
definition = function(x, na.rm = FALSE, verbose = getOption("arkhe.verbose")) {
|
|
| 32 | 5x |
compact(x, margin = 2, na.rm = na.rm, verbose = verbose) |
| 33 |
} |
|
| 34 |
) |
|
| 35 | ||
| 36 |
#' @export |
|
| 37 |
#' @rdname compact |
|
| 38 |
#' @aliases compact_rows,ANY-method |
|
| 39 |
setMethod( |
|
| 40 |
f = "compact_rows", |
|
| 41 |
signature = c(x = "ANY"), |
|
| 42 |
definition = function(x, na.rm = FALSE, verbose = getOption("arkhe.verbose")) {
|
|
| 43 | 7x |
compact(x, margin = 1, na.rm = na.rm, verbose = verbose) |
| 44 |
} |
|
| 45 |
) |