alike: Compare Object Structure

Description Usage Arguments Value alikeness .alike See Also Examples

View source: R/alike.R View source: R/alike.R

Description

Similar to all.equal, but compares object structure rather than value. The target argument defines a template that the current argument must match.

Usage

1
2
3
4
5
6
7
alike(target, current)

.alike(target, current, settings = alike_settings(env = parent.frame()))

alike_settings(type.mode = 0L, attr.mode = 0L, lang.mode = 0L,
  rec.mode = 0L, env = parent.frame(), fuzzy.int.max.len = 100L,
  suppress.warnings = FALSE, width = -1L, env.limit = 65536L)

Arguments

target

the template to compare the object to

current

the object to determine alikeness of to the template

settings

a list of settings for .alike generated using alike_settings

type.mode

integer(1L) in 0:2, see mode parameter to type_alike

attr.mode

integer(1L) in 0:2 determines strictness of attribute comparison:

  • 0 only checks attributes that are present in target, and uses special comparisons for the special attributes (class, dim, dimnames, names, row.names, levels, srcref, and tsp) while requiring other attributes to be alike

  • 1 is like 0, except all atributes must be alike

  • 2 requires all attributes to be present in target and current and to be alike

lang.mode

integer(1L) in 0:1 controls language matching, set to '1' to turn off use of match.call

rec.mode

integer(1L) '0' currently unused, intended to control how recursive structures (other than language objects) are compared

env

environment used internally when evaluating expressions; currently used only when looking up functions to match.call when testing language objects

fuzzy.int.max.len

see same parameter for type_alike

suppress.warnings

logical(1L)

width

to use when deparsing expressions; defaults to getOption("width")

env.limit

integer(1L) maximum number of nested environments to recurse through; these are tracked to make sure we do not get into an infinite recursion loop, but because they are tracked we keep a limit on how many we will go through.

Value

TRUE if target and current are alike, character(1L) describing why they are not if they are not

alikeness

Generally speaking two objects are alike if they are of the same type (as determined by type_alike) and length. Attributes on the objects are required to be recursively alike, though the following attributes are treated specially: class, dim, dimnames, names, row.names, levels, tsp, and srcref.

Exactly what makes two objects alike is complex, but should be intuitive. The best way to understand "alikeness" is to review the examples. For a thorough exposition see the vignette.

Note that the semantics of alikeness for language objects, formulas, and functions may change in the future.

.alike

.alike is identical to alike, except that it exposes the settings parameter that modifies certain aspects of how "alikeness" is computed. There is only one settings parameter to minimize the overhead associated with .alike. If you intend to run .alike as part of a process that runs many times, consider defining the value for settings outside of the function call once:

1
2
  sets <- alike_settings(...)                  # specify settings once
  for(i in 1e5) .alike(x[[i]], y[[i]], sets)   # re-use settings 1e5 times

See Also

type_alike, type_of, abstract

Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
## Type comparison
alike(1L, 1.0)         # TRUE, because 1.0 is integer-like
alike(1L, 1.1)         # FALSE, 1.1 is not integer-like
alike(1.1, 1L)         # TRUE, by default, integers are always considered real

alike(1:100, 1:100 + 0.0)  # TRUE

## We do not check numerics for integerness if longer than 100
alike(1:101, 1:101 + 0.0)

## Scalarness can now be checked at same time as type
alike(integer(1L), 1)            # integer-like and length 1?
alike(logical(1L), TRUE)         # logical and length 1?
alike(integer(1L), 1:3)
alike(logical(1L), c(TRUE, TRUE))

## Zero length match any length of same type
alike(integer(), 1:10)
alike(1:10, integer())   # but not the other way around

## Recursive objects compared recursively
alike(
  list(integer(), list(character(), logical(1L))),
  list(1:10, list(letters, TRUE))
)
alike(
  list(integer(), list(character(), logical(1L))),
  list(1:10, list(letters, c(TRUE, FALSE)))
)

## `NULL` is a wild card when nested within recursive objects
alike(list(NULL, NULL), list(iris, mtcars))
alike(NULL, mtcars)    # but not at top level

## Since `data.frame` are lists, we can compare them recursively:
iris.fake <- transform(iris, Species=as.character(Species))
alike(iris, iris.fake)

## we even check attributes (factor levels must match)!
iris.fake2 <- iris.fake
levels(iris.fake2$Species) <- c("setosa", "versicolor", "africana")
alike(iris, iris.fake2)

## We can use partially specified objects as templates
iris.tpl <- abstract(iris)
str(iris.tpl)
alike(iris.tpl, iris)
## any row sample of iris matches our iris template
alike(iris.tpl, iris[sample(1:nrow(iris), 10), ])
## but column order matters
alike(iris.tpl, iris[c(2, 1, 3, 4, 5)])

## 3 x 3 integer
alike(matrix(integer(), 3, 3), matrix(1:9, nrow=3))
## 3 x 3, but not integer!
alike(matrix(integer(), 3, 3), matrix(runif(9), nrow=3))
## partial spec, any 3 row integer matrix
alike(matrix(integer(), 3), matrix(1:12, nrow=3))
alike(matrix(integer(), 3), matrix(1:12, nrow=4))
## Any logical matrix (but not arrays)
alike(matrix(logical()), array(rep(TRUE, 8), rep(2, 3)))

## In order for objects to be alike, they must share a family
## tree, not just a common class
obj.tpl <- structure(TRUE, class=letters[1:3])
obj.cur.1 <-  structure(TRUE, class=c("x", letters[1:3]))
obj.cur.2 <-  structure(TRUE, class=c(letters[1:3], "x"))

alike(obj.tpl, obj.cur.1)
alike(obj.tpl, obj.cur.2)

## You can compare language objects; these are alike if they are self
## consistent; we don't care what the symbols are, so long as they are used
## consistently across target and current:

## TRUE, symbols are consistent (adding two different symbols)
alike(quote(x + y), quote(a + b))
## FALSE, different function
alike(quote(x + y), quote(a - b))
## FALSE, inconsistent symbols
alike(quote(x + y), quote(a + a))

brodieG/alike documentation built on June 4, 2017, 7:43 a.m.