Evaluate an Expression in Parallel for Multiple Imputations

DESCRIPTION:

For each multiple imputation set in the objects used in an expression, replace missing data by the set and evaluate the expression.

USAGE:

miEval(expr, vnames, simplify = F, trace = T) 
miEvalA(expr, vnames, simplify = F, trace = T) 

REQUIRED ARGUMENTS:

expr
An S-PLUS expression involving data with multiple imputations.

OPTIONAL ARGUMENTS:

vnames
character vector of names of all objects used in expr which either contain multiple imputations or are assigned. Note -- some code will not work correctly unless you supply this argument, see the "Identification" section below.
simplify
if TRUE, then the return value and all other objects created are simplified if their imputations are identical.
trace
if TRUE or 1 then diagnostic information is printed. If 2 then additional information is printed.

VALUE:

an object of class miList, for which each component contains the result of evaluating expr with a single set of multiple imputations.

If simplify=TRUE and all components are identical, then just one component is returned (i.e. the miList is simplified to an ordinary object).

SIDE EFFECTS:

Assignments in expr are carried out. The resulting objects will be miList objects (or possibly ordinary objects, if simplify=TRUE). If any modified objects were data frames containing miVariable variables, use data.frame or as.data.frame to convert them back to a data frame, and miTrim to convert variables without missing values (or with identical imputations) into ordinary objects.

DETAILS:

miEval proceeds in three steps: identification of mi variables, setup, and evaluate a modified version of expr in a loop.

-Identification (if vnames not supplied):

The function first parses expr to identify mi objects. For instance, in

miEval({ a <- mean(x); b <- a + y})

objects a and b are assigned and x and y are used. All assigned variables, and any other variables which contain multiple imputations, are mi objects.

miEval uses special logic for determining mi objects when expr is a call to a function for which both a data argument and a formula are supplied as arguments. For example, if MyData contains variables x, y and z, then only MyData is an mi object in:

fit <- miEval(lm(y~x+z, data = MyData))

In some cases miEval cannot determine which variables are mi objects, and you must supply vnames. E.g. in

fit <- miEval(coef(lm(y~x+z, data = MyData)), vnames="MyData")

the special logic is not used is not used if vnames is omitted. Similarly, in

miEval(update(fit, .~.-z), vnames = "fit")

it is necessary to specify vnames="fit" because otherwise the function cannot tell that z is not an object to be used.

It is possible to make assignments within expr, and the assigments will persist after miEval is finished. If expr contains any assignments, then miEval calls miEvalA; miEvalA may also be called directly. It is generally best to avoid assignments within the expression, as miEvalA is slower than miEval and does not have the special logic mentioned above, so specifying vnames is necessary:

miEval(fit <- lm(y~x+z, data = MyData, vnames = "MyData")
miEvalA(fit <- lm(y~x+z, data = MyData, vnames = "MyData")
fit <- miEval(lm(y~x+z, data = MyData) # simplest alternative




If vnames is used then all mi objects should be listed.

-Setup:

Once mi objects have been identified, miEval determines the number "M" and names of imputation sets, and makes sure that all objects which are assigned in the expression are miList objects in the frame of the caller of miEval, either by creating them if they did not previously exist, or converting ordinary or other mi objects to miList objects.

-Loop:

Then for m = 1 to M, every instance of the name of a mi object (say x) in expr is replaced with miSubscript(x,m*), where m* is the value of m (not the name "m"), and the modified expression is evaluated in the frame of the caller. For example, if x contains imputations and a does not, then in

miEval(ans <- mean(x, trim = a))

the modified expression is (for m=1)

miSubscript(ans, 1) <- mean(miSubscript(x, 1), trim = a)

Missing values in x are replaced with the first set of multiple imputations, the trimmed mean computed, and the result assigned to the first component of ans.

miEval returns an miList object, whose M components contain the values of the M evaluations of the modified expression. Hence, the previous example could (and should) be written

ans <- miEval(mean(x, trim = a))

NOTE:

Calls to get, assign, <<-, attach, detach, rm, and remove are not supported.

SEE ALSO:

, , , .

EXAMPLES:

miEval(mean(cholesterolImpExample[[3]])) 
# May specify name(s) of mi objects. 
# expr could be quite complicated. 
miEval(mean(  cholesterolImpExample[[3]]) -  
       median(cholesterolImpExample[[3]]), 
       "cholesterolImpExample") 
fit <- miEval(lm(chol14 ~ ., data = cholesterolImpExample)) 
fit[[1]]$call        # Note how lm was actually called, 
fit[[2]]$call        # using miSubscript 
miEval(summary(fit)) 
x <- cholesterolImpExample 
miEval(x[[3]] <- rev(x[[3]])) 
# side effect:  x is now an miList object 
x <- as.data.frame(x) 
x[[1]]               # miVariable, with no imputations 
y <- miTrim(x) 
y[[1]]               # ordinary object