Note that in R, categorical predictors are represented by 'factors'. For example, a 'Group' variable with three factor levels: 'Low', 'Medium' and 'High'. The constraint syntax can be specified in two ways:
First, and probably the easiest way is to specify constraints using a text-based description. In case of a categorical predictor constraints can be specified using the factor-level name preceded by the factor name. In case of a continuous predictor constraints can be specified by the variable name. For example, if we have a factor 'Group' with three levels (Low, Medium, High) and three covariates (x1-x3) the constraint syntax might look as follows:
myConstraints <- '
# 1. factor with three levels
GroupLow < GroupMedium = GroupHigh
! 2. continuous predictors
x1 < x2
x3 > 0 '
Blank lines and comments can be used in between the constraints, and constraints can be split over multiple lines. Both the hashtag (#) and the exclamation (!) characters can be used to start a comment. Multiple constraints can be placed on a single line if they are separated by a semicolon (;). It is important to note that, the constraint syntax is enclosed within single quotes.
There can be three types of text-based descriptions in the constraints syntax:
Equality constraints: The =
" operator can be
used to define equality constraints (e.g., x1 = 1
or
x1 = x2
).
Inequality constraints: The <
" or >
"
operator can be used to define inequality constraints
(e.g., x1 > 1
or x1 < x2
).
Newly defined parameters: The :=
" operator can
be used to define new parameters, which take on values that
are an arbitrary function of the original model parameters.
The function must be specified in terms of the parameter names. By
default, the standard errors for these defined parameters are
computed by using the so-called Delta method.
In R, variable names of interaction effects in objects of class lm and rlm contain a
semi-colon (:) between the variable names. To impose constraints on parameters of
interaction effects, the semi-colon must be replaced by a dot (.) (e.g.,
x3:x4
becomes x3.x4
). In addition, the intercept variable
name is shown as (Intercept)
". To impose restrictions on the intercept
both parentheses must be replaced by a dot .Intercept.
" (e.g.,.Intercept. > 10
).
Note: in most practical situations we do not impose restrictions on the intercept
because we do not have prior knowledge about the intercept. Moreover, the sign of
the intercept can be changed arbitrarily by shifting the response variable y
.
Each element can be modified using arithmetic operators. For example, if x2
is expected to be twice as large as x1
, then 2*x2 = x1
".
Another example is (x1 + 0.5*x2) > x3
".
Second, the constraint syntax can be written in matrix notation. The syntax consists of a matrix R (or a vector in case of one constraint) and defines the left-hand side of the constraint $R\theta \geq \text{rhs}$, where each row represents one constraint. The number of columns needs to correspond to the number of estimated parameters ($\theta$). The rows should be linear independent, otherwise the function gives an error. Then, the above constraint syntax can be specified as follows:
myConstraints <-
rbind(c( 0,-1, 1, 0, 0, 0), #GroupMedium = GroupHigh
c(-1, 1, 0, 0, 0, 0), #GroupLow < GroupMedium
c( 0, 0, 0,-1, 1, 0), #x1 < x2
c( 0, 0, 0, 0, 0, 1)) #x3 > 0
# the length of rhs is equal to the number of myConstraints rows.
myRhs <- c(0,0,0,0)
# the first row should be treated as an equality constraint
myNeq <- 1