Guest User

Untitled

a guest
Sep 20th, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.29 KB | None | 0 0
  1. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2. #' A strict version of '%in%' where both the in-group and out-group must be completely specified
  3. #'
  4. #' The membership test is strict.
  5. #' - if 'universe' is defined, then `outgroup = setdiff(universe, ingroup)`
  6. #' - Every value of 'x' must exist within either 'ingroup' or 'outgroup'
  7. #' - 'ingroup' and 'outgroup' must be disjoint sets
  8. #' - May specify only one of 'outgroup' or 'universe'
  9.  
  10. #'
  11. #' @param x input values.
  12. #' @param ingroup vector of values against which elements of 'x' should be checked
  13. #' for membership.
  14. #' @param outgroup vector of values to which the elements of 'x' should not belong
  15. #' @param universe vector of all possible values to expect
  16. #'
  17. #'
  18. #' @return A logical vector the same length as 'x' which is TRUE if the
  19. #' correponding value in x is a member of 'ingroup' and is not a member
  20. #' of 'outgroup'.
  21. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  22. is_within <- function(x, ingroup, outgroup=NULL, universe=NULL) {
  23.  
  24. if (!xor(is.null(outgroup), is.null(universe))) {
  25. stop("is_within(): Must only specify one (and only one) of 'outgroup' or 'universe'")
  26. }
  27.  
  28. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  29. # Define outgroup to be disjoint from ingroup if 'universe' given,
  30. # otherwise check that given ingroup/group are disjoint
  31. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  32. if (!is.null(universe)) {
  33. outgroup <- setdiff(universe, ingroup)
  34. } else {
  35. if (length(intersect(ingroup, outgroup)) > 0L) {
  36. stop("is_within(): 'ingroup' and 'outgroup' must not have overlapping elements. The following elements were found in both - ",
  37. deparse(intersect(ingroup, outgroup)))
  38. }
  39. }
  40.  
  41. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  42. # Check classes match
  43. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  44. if (length(intersect(class(x), intersect(class(ingroup), class(outgroup)))) == 0L) {
  45. stop("is_within(): Classes must be identical. x: ", deparse(class(x)),
  46. " ingroup: ", deparse(class(ingroup)), " outgroup: ", deparse(class(outgroup)))
  47. }
  48.  
  49. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  50. # Check inputs have length >= 1
  51. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  52. if (length(x) == 0L) { stop("is_within(): 'x' must have at least 1 element")}
  53. if (length(ingroup) == 0L) { stop("is_within(): 'ingroup' must have at least 1 element")}
  54.  
  55. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  56. # Actually perform the membership tests
  57. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  58. res <- x %in% ingroup
  59. neg <- x %in% outgroup
  60.  
  61. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  62. # Check: input values must appear in one of 'ingroup' or 'outgroup', but not both.
  63. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  64. if (any(!xor(res, neg))) {
  65. stop("is_within(): All elements should appear in the 'ingroup' or 'outgroup' vectors. The following input elements were not found in either - ", deparse(x[!xor(res, neg)]))
  66. }
  67.  
  68.  
  69. res
  70. }
Add Comment
Please, Sign In to add comment