Deductive imputation of numerical or categorical values

Share:

Description

Based on observed values and edit rules, impute as many variables deductively as possible.

If E is an editset, imputation based on numerical rules (if any) is performed, and imputations violating extra edits are reverted. Next, this procedure is repeated for pure categorical rules. The results are combined and returned in a deducorrect object.

For categorical data: The funcion deductiveLevels is used to derive deductive imputations for as many fields as possible

For numerical data: Given (equality) rules and a number of values to impute or adapt, in some cases unique solutions can be derived. This function uses solSpace and deductiveZeros (iteratively) to determine which values can be imputed deductively. Solutions causing new violations of (in)equality rules are rejected by default by testing if the observed values can lead to a feasible record. This may be switched off by passing checkFeasibility=FALSE. This may be desirable for performance reasons. If adapt was computed with an error localization algorithm, such as editrules::localizeErrors, the feasibility check is also not nessecary.

Usage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
deduImpute(E, dat, adapt = NULL, ...)

## S3 method for class 'editset'
deduImpute(E, dat, adapt = NULL, ...)

## S3 method for class 'editarray'
deduImpute(E, dat, adapt = NULL, ...)

## S3 method for class 'editmatrix'
deduImpute(E, dat, adapt = NULL,
  tol = sqrt(.Machine$double.eps), round = TRUE, ...)

Arguments

E

An editmatrix or editarray

dat

A data.frame

adapt

(optional) A boolean array of dim(dat), e.g. the result editrules::localizeErrors(E,dat). Column names must match those of dat.

...

arguments to be passed to solSpace (numerical data) or deductiveLevels (categorical data)

tol

tolerance to use in solSpace and in deductiveZeros

round

should the result be rounded?

Value

A deducorrect-object

Note

When adapt is not NULL, values in dat where adapt==TRUE are replaced with NA. The output may therefore contain missings at positions that were previously filled (with wrong values, according to adapt).

References

T. De Waal, J. Pannekoek and S. Scholtus (2011) Handbook of statistical data editing Chpt 9.2.1 - 9.2.2

See Also

deductiveZeros, solSpace, deductiveLevels

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
82
83
84
85
86
87
88
89
90
91
#############################################
# IMPUTATION OF NUMERIC DATA
#############################################

# These examples are taken from De Waal et al (2011) (Examples 9.1-9.2)
E <- editmatrix(c(
    "x1 + x2      == x3",
    "x2           == x4",
    "x5 + x6 + x7 == x8",
    "x3 + x8      == x9",
    "x9 - x10     == x11",
    "x6 >= 0",
    "x7 >= 0"
))


dat <- data.frame(
    x1=c(145,145),
    x2=c(NA,NA),
    x3=c(155,155),
    x4=c(NA,NA),
    x5=c(NA, 86),
    x6=c(NA,NA),
    x7=c(NA,NA),
    x8=c(86,86),
    x9=c(NA,NA),
    x10=c(217,217),
    x11=c(NA,NA)
)

dat

d <- deduImpute(E,dat)
d$corrected
d$status
d$corrections




#############################################
# IMPUTATION OF CATEGORICAL DATA
#############################################


# Here's an example from Katrika (2001) [but see De Waal et al (2011), ex. 9.3)]
E <- editarray(c(
    "x1 \%in\% letters[1:4]",
    "x2 \%in\% letters[1:3]",
    "x3 \%in\% letters[1:3]",
    "x4 \%in\% letters[1:2]",
    "if (x2 == 'c'  & x3 != 'c' & x4 == 'a' ) FALSE",
    "if (x2 != 'a'  & x4 == 'b') FALSE",
    "if (x1 != 'c'  & x2 != 'b' & x3 != 'a') FALSE",
    "if (x1 == 'c'  & x3 != 'a' & x4 == 'a' ) FALSE"
))


dat <- data.frame(
    x1 = c('c', NA ),
    x2 = c('b', NA ),
    x3 = c(NA , NA ),
    x4 = c(NA , 'b'),
    stringsAsFactors=FALSE)


s <- deduImpute(E,dat)
s$corrected
s$status
s$corrections


E <- editset(expression(
    x + y == z,
    x >= 0,
    A %in% c('a','b'),
    B %in% c('c','d'),
    if ( A == 'a' ) B == 'b',
    if ( B == 'b' ) x > 0
))

x <- data.frame(
    x = NA,
    y = 1,
    z = 1,
    A = 'a',
    B = NA
)
# deduImpute will impute x=0 and B='b',which violates the 
# last edit. Hence, imputation will be reverted.
deduImpute(E,x) 

Want to suggest features or report bugs for rdrr.io? Use the GitHub issue tracker.