# fill: Creates a Matrix of Appropriate Dimension In VGAM: Vector Generalized Linear and Additive Models

## Description

A support function for the argument `xij`, it generates a matrix of an appropriate dimension.

## Usage

 `1` ```fill(x, values = 0, ncolx = ncol(x)) ```

## Arguments

 `x` A vector or matrix which is used to determine the dimension of the answer, in particular, the number of rows. After converting `x` to a matrix if necessary, the answer is a matrix of `values` values, of dimension `nrow(x)` by `ncolx`. `values` Numeric. The answer contains these values, which are recycled columnwise if necessary, i.e., as `matrix(values, ..., byrow=TRUE)`. `ncolx` The number of columns of the returned matrix. The default is the number of columns of `x`.

## Details

The `xij` argument for `vglm` allows the user to input variables specific to each linear/additive predictor. For example, consider the bivariate logit model where the first/second linear/additive predictor is the logistic regression of the first/second binary response respectively. The third linear/additive predictor is ```log(OR) = eta3```, where `OR` is the odds ratio. If one has ocular pressure as a covariate in this model then `xij` is required to handle the ocular pressure for each eye, since these will be different in general. [This contrasts with a variable such as `age`, the age of the person, which has a common value for both eyes.] In order to input these data into `vglm` one often finds that functions `fill`, `fill1`, etc. are useful.

All terms in the `xij` and `formula` arguments in `vglm` must appear in the `form2` argument too.

## Value

`matrix(values, nrow=nrow(x), ncol=ncolx)`, i.e., a matrix consisting of values `values`, with the number of rows matching `x`, and the default number of columns is the number of columns of `x`.

## Note

The effect of the `xij` argument is after other arguments such as `exchangeable` and `zero`. Hence `xij` does not affect constraint matrices.

Additionally, there are currently 3 other identical `fill` functions, called `fill1`, `fill2` and `fill3`; if you need more then assign `fill4 = fill5 = fill1` etc. The reason for this is that if more than one `fill` function is needed then they must be unique. For example, if M=4 then `xij = op ~ lop + rop + fill(mop) + fill(mop)` would reduce to `xij = op ~ lop + rop + fill(mop)`, whereas `xij = op ~ lop + rop + fill1(mop) + fill2(mop)` would retain all M terms, which is needed.

In Examples 1 to 3 below, the `xij` argument illustrates covariates that are specific to a linear predictor. Here, `lop`/`rop` are the ocular pressures of the left/right eye in an artificial dataset, and `mop` is their mean. Variables `leye` and `reye` might be the presence/absence of a particular disease on the LHS/RHS eye respectively.

In Example 3, the `xij` argument illustrates fitting the (exchangeable) model where there is a common smooth function of the ocular pressure. One should use regression splines since `s` in `vgam` does not handle the `xij` argument. However, regression splines such as `bs` and `ns` need to have the same basis functions here for both functions, and Example 3 illustrates a trick involving a function `BS` to obtain this, e.g., same knots. Although regression splines create more than a single column per term in the model matrix, `fill(BS(lop,rop))` creates the required (same) number of columns.

## Author(s)

T. W. Yee

`vglm.control`, `vglm`, `multinomial`, `Select`.
 ``` 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``` ```fill(runif(5)) fill(runif(5), ncol = 3) fill(runif(5), val = 1, ncol = 3) # Generate eyes data for the examples below. Eyes are independent (OR=1). nn <- 1000 # Number of people eyesdata <- data.frame(lop = round(runif(nn), 2), rop = round(runif(nn), 2), age = round(rnorm(nn, 40, 10))) eyesdata <- transform(eyesdata, mop = (lop + rop) / 2, # Mean ocular pressure op = (lop + rop) / 2, # Value unimportant unless plotting # op = lop, # Choose this if plotting eta1 = 0 - 2*lop + 0.04*age, # Linear predictor for left eye eta2 = 0 - 2*rop + 0.04*age) # Linear predictor for right eye eyesdata <- transform(eyesdata, leye = rbinom(nn, size = 1, prob = logitlink(eta1, inverse = TRUE)), reye = rbinom(nn, size = 1, prob = logitlink(eta2, inverse = TRUE))) # Example 1. All effects are linear. fit1 <- vglm(cbind(leye,reye) ~ op + age, family = binom2.or(exchangeable = TRUE, zero = 3), data = eyesdata, trace = TRUE, xij = list(op ~ lop + rop + fill(lop)), form2 = ~ op + lop + rop + fill(lop) + age) head(model.matrix(fit1, type = "lm")) # LM model matrix head(model.matrix(fit1, type = "vlm")) # Big VLM model matrix coef(fit1) coef(fit1, matrix = TRUE) # Unchanged with 'xij' constraints(fit1) max(abs(predict(fit1)-predict(fit1, new = eyesdata))) # Predicts correctly summary(fit1) ## Not run: plotvgam(fit1, se = TRUE) # Wrong, e.g., because it plots against op, not lop. # So set op = lop in the above for a correct plot. ## End(Not run) # Example 2. This model uses regression splines on ocular pressure. # It uses a trick to ensure common basis functions. BS <- function(x, ...) sm.bs(c(x,...), df = 3)[1:length(x), , drop = FALSE] # trick fit2 <- vglm(cbind(leye,reye) ~ BS(lop,rop) + age, family = binom2.or(exchangeable = TRUE, zero = 3), data = eyesdata, trace = TRUE, xij = list(BS(lop,rop) ~ BS(lop,rop) + BS(rop,lop) + fill(BS(lop,rop))), form2 = ~ BS(lop,rop) + BS(rop,lop) + fill(BS(lop,rop)) + lop + rop + age) head(model.matrix(fit2, type = "lm")) # LM model matrix head(model.matrix(fit2, type = "vlm")) # Big VLM model matrix coef(fit2) coef(fit2, matrix = TRUE) summary(fit2) fit2@smart.prediction max(abs(predict(fit2) - predict(fit2, new = eyesdata))) # Predicts correctly predict(fit2, new = head(eyesdata)) # Note the 'scalar' OR, i.e., zero=3 max(abs(head(predict(fit2)) - predict(fit2, new = head(eyesdata)))) # Should be 0 ## Not run: plotvgam(fit2, se = TRUE, xlab = "lop") # Correct ## End(Not run) # Example 3. Capture-recapture model with ephemeral and enduring # memory effects. Similar to Yang and Chao (2005), Biometrics. deermice <- transform(deermice, Lag1 = y1) M.tbh.lag1 <- vglm(cbind(y1, y2, y3, y4, y5, y6) ~ sex + weight + Lag1, posbernoulli.tb(parallel.t = FALSE ~ 0, parallel.b = FALSE ~ 0, drop.b = FALSE ~ 1), xij = list(Lag1 ~ fill(y1) + fill(y2) + fill(y3) + fill(y4) + fill(y5) + fill(y6) + y1 + y2 + y3 + y4 + y5), form2 = ~ sex + weight + Lag1 + fill(y1) + fill(y2) + fill(y3) + fill(y4) + fill(y5) + fill(y6) + y1 + y2 + y3 + y4 + y5 + y6, data = deermice, trace = TRUE) coef(M.tbh.lag1) ```