Given a bipartite matching (object of class `optmatch`

),
create a logical vector of the same length indicating which units
were and were not placed into matched sets.

## Details

`matched`

and `unmatched`

indicate which elements of
`x`

do and do not belong to matched sets, as indicated by
their character representations in `x`

.

When `fullmatch`

has been presented with an inconsistent
combination of constraints and discrepancies between potential
matches, so that there exists no matching (i) with finite total
discrepancy within matched sets that (ii) respects the given
constraints, then the matching problem is said to be infeasible.
`TRUE`

s in the output of `matchfailed`

indicate that
this has occurred.

## Note

To understand the output of `matchfailed`

element-wise,
note that `fullmatch`

handles a matching problem in three
steps. First, if `fullmatch`

has been directed to match
within subclasses, then it divides its matching problem into a
subproblem for each subclass. Second, `fullmatch`

removes
from each subproblem those individual units that lack
permissible potential matches (i.e. potential matches from which
they are separated by a finite discrepancy). Such "isolated"
units are flagged in such a way as to be indicated by
`unmatched`

, but not by `matchfailed`

. Third,
`fullmatch`

presents each subproblem, with isolated
elements removed, to an optimal matching routine. If such a
reduced subproblem is found at this stage to be infeasible, then
each unit contributing to it is so flagged as to be indicated by
`matchfailed`

.

## Examples

```
data(plantdist)
mxpl.fm0 <- fullmatch(plantdist) # A feasible matching problem
#> Warning: Without 'data' argument the order of the match is not guaranteed
#> to be the same as your original data.
c(sum(matched(mxpl.fm0)), sum(unmatched(mxpl.fm0)))
#> [1] 26 0
sum(matchfailed(mxpl.fm0))
#> [1] 0
mxpl.fm1 <- fullmatch(plantdist, # An infeasible problem
max.controls=3, min.controls=3)
#> Warning: Without 'data' argument the order of the match is not guaranteed
#> to be the same as your original data.
#> Warning: Matching failed. (Restrictions impossible to meet?)
#> Enter ?matchfailed for more info.
c(sum(matched(mxpl.fm1)), sum(unmatched(mxpl.fm1)))
#> [1] 0 26
sum(matchfailed(mxpl.fm1))
#> [1] 26
mxpl.si <- factor(c('a', 'a', 'c', rep('d',4), 'b', 'c', 'c', rep('d', 16)))
names(mxpl.si) <- LETTERS[1:26]
mxpl.exactmatch <- exactMatch(mxpl.si, c(rep(1, 7), rep(0, 26 - 7)))
# Subclass a contains two treated units but no controls;
# subclass b contains only a control unit;
# subclass c contains one treated and two control units;
# subclass d contains the remaining twenty units.
# only valid subproblems will be used
mcl <- c(1, Inf)
mxpl.fm2 <- fullmatch(plantdist + mxpl.exactmatch,
max.controls=mcl)
#> Warning: Without 'data' argument the order of the match is not guaranteed
#> to be the same as your original data.
sum(matched(mxpl.fm2))
#> [1] 22
table(unmatched(mxpl.fm2), matchfailed(mxpl.fm2))
#>
#> FALSE
#> FALSE 22
#> TRUE 1
mxpl.fm2[matchfailed(mxpl.fm2)]
#> factor(0)
mxpl.fm2[unmatched(mxpl.fm2) & # isolated units return as
!matchfailed(mxpl.fm2)] # unmatched but not matchfailed
#> I
#> <NA>
```