Shows what matrices \(A, b\) look like as the system of linear equations, \(A x = b\), but written out as a set of equations.

showEqn(
  A,
  b,
  vars,
  simplify = FALSE,
  reduce = FALSE,
  fractions = FALSE,
  latex = FALSE
)

Arguments

A

either the matrix of coefficients of a system of linear equations, or the matrix cbind(A,b). Alternatively, can be of class 'lm' to print the equations for the design matrix in a linear regression model

b

if supplied, the vector of constants on the right hand side of the equations. When omitted the values b1, b2, ..., bn will be used as placeholders

vars

a numeric or character vector of names of the variables. If supplied, the length must be equal to the number of unknowns in the equations. The default is paste0("x", 1:ncol(A).

simplify

logical; try to simplify the equations?

reduce

logical; only show the unique linear equations

fractions

logical; express numbers as rational fractions, using the fractions function; if you require greater accuracy, you can set the cycles (default 10) and/or max.denominator (default 2000) arguments to fractions as a global option, e.g., options(fractions=list(cycles=100, max.denominator=10^4)).

latex

logical; print equations in a form suitable for LaTeX output?

Value

a one-column character matrix, one row for each equation

References

Fox, J. and Friendly, M. (2016). "Visualizing Simultaneous Linear Equations, Geometric Vectors, and Least-Squares Regression with the matlib Package for R". useR Conference, Stanford, CA, June 27 - June 30, 2016.

See also

Author

Michael Friendly, John Fox, and Phil Chalmers

Examples

  A <- matrix(c(2, 1, -1,
               -3, -1, 2,
               -2,  1, 2), 3, 3, byrow=TRUE)
  b <- c(8, -11, -3)
  showEqn(A, b)
#>  2*x1 + 1*x2 - 1*x3  =    8 
#> -3*x1 - 1*x2 + 2*x3  =  -11 
#> -2*x1 + 1*x2 + 2*x3  =   -3 
  # show numerically
  x <- solve(A, b)
  showEqn(A, b, vars=x)
#>  2*2 + 1*3 - 1*-1  =    8 
#> -3*2 - 1*3 + 2*-1  =  -11 
#> -2*2 + 1*3 + 2*-1  =   -3 

  showEqn(A, b, simplify=TRUE)
#>  2*x1   + x2 - 1*x3  =    8 
#> -3*x1 - 1*x2 + 2*x3  =  -11 
#> -2*x1   + x2 + 2*x3  =   -3 
  showEqn(A, b, latex=TRUE)
#> \begin{array}{lllllll}
#>  2 \cdot x_1 &+& 1 \cdot x_2 &-& 1 \cdot x_3  &=&    8 \\ 
#> -3 \cdot x_1 &-& 1 \cdot x_2 &+& 2 \cdot x_3  &=&  -11 \\ 
#> -2 \cdot x_1 &+& 1 \cdot x_2 &+& 2 \cdot x_3  &=&   -3 \\ 
#> \end{array}

  # lower triangle of equation with zeros omitted (for back solving)
  A <- matrix(c(2, 1, 2,
               -3, -1, 2,
               -2,  1, 2), 3, 3, byrow=TRUE)
  U <- LU(A)$U
  showEqn(U, simplify=TRUE, fractions=TRUE)
#> 2*x1  + x2  + 2*x3  =  b1 
#>     1/2*x2  + 5*x3  =  b2 
#>            - 16*x3  =  b3 
  showEqn(U, b, simplify=TRUE, fractions=TRUE)
#> 2*x1  + x2  + 2*x3  =    8 
#>     1/2*x2  + 5*x3  =  -11 
#>            - 16*x3  =   -3 

  ####################
  # Linear models Design Matricies
  data(mtcars)
  ancova <- lm(mpg ~ wt + vs, mtcars)
  summary(ancova)
#> 
#> Call:
#> lm(formula = mpg ~ wt + vs, data = mtcars)
#> 
#> Residuals:
#>     Min      1Q  Median      3Q     Max 
#> -3.7071 -2.4415 -0.3129  1.4319  6.0156 
#> 
#> Coefficients:
#>             Estimate Std. Error t value Pr(>|t|)    
#> (Intercept)  33.0042     2.3554  14.012 1.92e-14 ***
#> wt           -4.4428     0.6134  -7.243 5.63e-08 ***
#> vs            3.1544     1.1907   2.649   0.0129 *  
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> Residual standard error: 2.78 on 29 degrees of freedom
#> Multiple R-squared:  0.801,	Adjusted R-squared:  0.7873 
#> F-statistic: 58.36 on 2 and 29 DF,  p-value: 6.818e-11
#> 
  showEqn(ancova)
#> 1*x1  + 2.62*x2 + 0*x3  =   b1 
#> 1*x1 + 2.875*x2 + 0*x3  =   b2 
#> 1*x1  + 2.32*x2 + 1*x3  =   b3 
#> 1*x1 + 3.215*x2 + 1*x3  =   b4 
#> 1*x1  + 3.44*x2 + 0*x3  =   b5 
#> 1*x1  + 3.46*x2 + 1*x3  =   b6 
#> 1*x1  + 3.57*x2 + 0*x3  =   b7 
#> 1*x1  + 3.19*x2 + 1*x3  =   b8 
#> 1*x1  + 3.15*x2 + 1*x3  =   b9 
#> 1*x1  + 3.44*x2 + 1*x3  =  b10 
#> 1*x1  + 3.44*x2 + 1*x3  =  b11 
#> 1*x1  + 4.07*x2 + 0*x3  =  b12 
#> 1*x1  + 3.73*x2 + 0*x3  =  b13 
#> 1*x1  + 3.78*x2 + 0*x3  =  b14 
#> 1*x1  + 5.25*x2 + 0*x3  =  b15 
#> 1*x1 + 5.424*x2 + 0*x3  =  b16 
#> 1*x1 + 5.345*x2 + 0*x3  =  b17 
#> 1*x1   + 2.2*x2 + 1*x3  =  b18 
#> 1*x1 + 1.615*x2 + 1*x3  =  b19 
#> 1*x1 + 1.835*x2 + 1*x3  =  b20 
#> 1*x1 + 2.465*x2 + 1*x3  =  b21 
#> 1*x1  + 3.52*x2 + 0*x3  =  b22 
#> 1*x1 + 3.435*x2 + 0*x3  =  b23 
#> 1*x1  + 3.84*x2 + 0*x3  =  b24 
#> 1*x1 + 3.845*x2 + 0*x3  =  b25 
#> 1*x1 + 1.935*x2 + 1*x3  =  b26 
#> 1*x1  + 2.14*x2 + 0*x3  =  b27 
#> 1*x1 + 1.513*x2 + 1*x3  =  b28 
#> 1*x1  + 3.17*x2 + 0*x3  =  b29 
#> 1*x1  + 2.77*x2 + 0*x3  =  b30 
#> 1*x1  + 3.57*x2 + 0*x3  =  b31 
#> 1*x1  + 2.78*x2 + 1*x3  =  b32 
  showEqn(ancova, simplify=TRUE)
#> x1  + 2.62*x2       =   b1 
#> x1 + 2.875*x2       =   b2 
#> x1  + 2.32*x2 + x3  =   b3 
#> x1 + 3.215*x2 + x3  =   b4 
#> x1  + 3.44*x2       =   b5 
#> x1  + 3.46*x2 + x3  =   b6 
#> x1  + 3.57*x2       =   b7 
#> x1  + 3.19*x2 + x3  =   b8 
#> x1  + 3.15*x2 + x3  =   b9 
#> x1  + 3.44*x2 + x3  =  b10 
#> x1  + 3.44*x2 + x3  =  b11 
#> x1  + 4.07*x2       =  b12 
#> x1  + 3.73*x2       =  b13 
#> x1  + 3.78*x2       =  b14 
#> x1  + 5.25*x2       =  b15 
#> x1 + 5.424*x2       =  b16 
#> x1 + 5.345*x2       =  b17 
#> x1   + 2.2*x2 + x3  =  b18 
#> x1 + 1.615*x2 + x3  =  b19 
#> x1 + 1.835*x2 + x3  =  b20 
#> x1 + 2.465*x2 + x3  =  b21 
#> x1  + 3.52*x2       =  b22 
#> x1 + 3.435*x2       =  b23 
#> x1  + 3.84*x2       =  b24 
#> x1 + 3.845*x2       =  b25 
#> x1 + 1.935*x2 + x3  =  b26 
#> x1  + 2.14*x2       =  b27 
#> x1 + 1.513*x2 + x3  =  b28 
#> x1  + 3.17*x2       =  b29 
#> x1  + 2.77*x2       =  b30 
#> x1  + 3.57*x2       =  b31 
#> x1  + 2.78*x2 + x3  =  b32 
  showEqn(ancova, vars=round(coef(ancova),2))
#> 1*33  + 2.62*-4.44 + 0*3.15  =   b1 
#> 1*33 + 2.875*-4.44 + 0*3.15  =   b2 
#> 1*33  + 2.32*-4.44 + 1*3.15  =   b3 
#> 1*33 + 3.215*-4.44 + 1*3.15  =   b4 
#> 1*33  + 3.44*-4.44 + 0*3.15  =   b5 
#> 1*33  + 3.46*-4.44 + 1*3.15  =   b6 
#> 1*33  + 3.57*-4.44 + 0*3.15  =   b7 
#> 1*33  + 3.19*-4.44 + 1*3.15  =   b8 
#> 1*33  + 3.15*-4.44 + 1*3.15  =   b9 
#> 1*33  + 3.44*-4.44 + 1*3.15  =  b10 
#> 1*33  + 3.44*-4.44 + 1*3.15  =  b11 
#> 1*33  + 4.07*-4.44 + 0*3.15  =  b12 
#> 1*33  + 3.73*-4.44 + 0*3.15  =  b13 
#> 1*33  + 3.78*-4.44 + 0*3.15  =  b14 
#> 1*33  + 5.25*-4.44 + 0*3.15  =  b15 
#> 1*33 + 5.424*-4.44 + 0*3.15  =  b16 
#> 1*33 + 5.345*-4.44 + 0*3.15  =  b17 
#> 1*33   + 2.2*-4.44 + 1*3.15  =  b18 
#> 1*33 + 1.615*-4.44 + 1*3.15  =  b19 
#> 1*33 + 1.835*-4.44 + 1*3.15  =  b20 
#> 1*33 + 2.465*-4.44 + 1*3.15  =  b21 
#> 1*33  + 3.52*-4.44 + 0*3.15  =  b22 
#> 1*33 + 3.435*-4.44 + 0*3.15  =  b23 
#> 1*33  + 3.84*-4.44 + 0*3.15  =  b24 
#> 1*33 + 3.845*-4.44 + 0*3.15  =  b25 
#> 1*33 + 1.935*-4.44 + 1*3.15  =  b26 
#> 1*33  + 2.14*-4.44 + 0*3.15  =  b27 
#> 1*33 + 1.513*-4.44 + 1*3.15  =  b28 
#> 1*33  + 3.17*-4.44 + 0*3.15  =  b29 
#> 1*33  + 2.77*-4.44 + 0*3.15  =  b30 
#> 1*33  + 3.57*-4.44 + 0*3.15  =  b31 
#> 1*33  + 2.78*-4.44 + 1*3.15  =  b32 
  showEqn(ancova, vars=round(coef(ancova),2), simplify=TRUE)
#> 33  + 2.62*-4.44         =   b1 
#> 33 + 2.875*-4.44         =   b2 
#> 33  + 2.32*-4.44 + 3.15  =   b3 
#> 33 + 3.215*-4.44 + 3.15  =   b4 
#> 33  + 3.44*-4.44         =   b5 
#> 33  + 3.46*-4.44 + 3.15  =   b6 
#> 33  + 3.57*-4.44         =   b7 
#> 33  + 3.19*-4.44 + 3.15  =   b8 
#> 33  + 3.15*-4.44 + 3.15  =   b9 
#> 33  + 3.44*-4.44 + 3.15  =  b10 
#> 33  + 3.44*-4.44 + 3.15  =  b11 
#> 33  + 4.07*-4.44         =  b12 
#> 33  + 3.73*-4.44         =  b13 
#> 33  + 3.78*-4.44         =  b14 
#> 33  + 5.25*-4.44         =  b15 
#> 33 + 5.424*-4.44         =  b16 
#> 33 + 5.345*-4.44         =  b17 
#> 33   + 2.2*-4.44 + 3.15  =  b18 
#> 33 + 1.615*-4.44 + 3.15  =  b19 
#> 33 + 1.835*-4.44 + 3.15  =  b20 
#> 33 + 2.465*-4.44 + 3.15  =  b21 
#> 33  + 3.52*-4.44         =  b22 
#> 33 + 3.435*-4.44         =  b23 
#> 33  + 3.84*-4.44         =  b24 
#> 33 + 3.845*-4.44         =  b25 
#> 33 + 1.935*-4.44 + 3.15  =  b26 
#> 33  + 2.14*-4.44         =  b27 
#> 33 + 1.513*-4.44 + 3.15  =  b28 
#> 33  + 3.17*-4.44         =  b29 
#> 33  + 2.77*-4.44         =  b30 
#> 33  + 3.57*-4.44         =  b31 
#> 33  + 2.78*-4.44 + 3.15  =  b32 

  twoway_int <- lm(mpg ~ vs * am, mtcars)
  summary(twoway_int)
#> 
#> Call:
#> lm(formula = mpg ~ vs * am, data = mtcars)
#> 
#> Residuals:
#>    Min     1Q Median     3Q    Max 
#> -6.971 -1.973  0.300  2.036  6.250 
#> 
#> Coefficients:
#>             Estimate Std. Error t value Pr(>|t|)    
#> (Intercept)   15.050      1.002  15.017 6.34e-15 ***
#> vs             5.693      1.651   3.448   0.0018 ** 
#> am             4.700      1.736   2.708   0.0114 *  
#> vs:am          2.929      2.541   1.153   0.2589    
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> Residual standard error: 3.472 on 28 degrees of freedom
#> Multiple R-squared:  0.7003,	Adjusted R-squared:  0.6682 
#> F-statistic: 21.81 on 3 and 28 DF,  p-value: 1.735e-07
#> 
  car::Anova(twoway_int)
#> Anova Table (Type II tests)
#> 
#> Response: mpg
#>           Sum Sq Df F value    Pr(>F)    
#> vs        367.41  1 30.4836 6.687e-06 ***
#> am        276.03  1 22.9021 4.984e-05 ***
#> vs:am      16.01  1  1.3283    0.2589    
#> Residuals 337.48 28                      
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
  showEqn(twoway_int)
#> 1*x1 + 0*x2 + 1*x3 + 0*x4  =   b1 
#> 1*x1 + 0*x2 + 1*x3 + 0*x4  =   b2 
#> 1*x1 + 1*x2 + 1*x3 + 1*x4  =   b3 
#> 1*x1 + 1*x2 + 0*x3 + 0*x4  =   b4 
#> 1*x1 + 0*x2 + 0*x3 + 0*x4  =   b5 
#> 1*x1 + 1*x2 + 0*x3 + 0*x4  =   b6 
#> 1*x1 + 0*x2 + 0*x3 + 0*x4  =   b7 
#> 1*x1 + 1*x2 + 0*x3 + 0*x4  =   b8 
#> 1*x1 + 1*x2 + 0*x3 + 0*x4  =   b9 
#> 1*x1 + 1*x2 + 0*x3 + 0*x4  =  b10 
#> 1*x1 + 1*x2 + 0*x3 + 0*x4  =  b11 
#> 1*x1 + 0*x2 + 0*x3 + 0*x4  =  b12 
#> 1*x1 + 0*x2 + 0*x3 + 0*x4  =  b13 
#> 1*x1 + 0*x2 + 0*x3 + 0*x4  =  b14 
#> 1*x1 + 0*x2 + 0*x3 + 0*x4  =  b15 
#> 1*x1 + 0*x2 + 0*x3 + 0*x4  =  b16 
#> 1*x1 + 0*x2 + 0*x3 + 0*x4  =  b17 
#> 1*x1 + 1*x2 + 1*x3 + 1*x4  =  b18 
#> 1*x1 + 1*x2 + 1*x3 + 1*x4  =  b19 
#> 1*x1 + 1*x2 + 1*x3 + 1*x4  =  b20 
#> 1*x1 + 1*x2 + 0*x3 + 0*x4  =  b21 
#> 1*x1 + 0*x2 + 0*x3 + 0*x4  =  b22 
#> 1*x1 + 0*x2 + 0*x3 + 0*x4  =  b23 
#> 1*x1 + 0*x2 + 0*x3 + 0*x4  =  b24 
#> 1*x1 + 0*x2 + 0*x3 + 0*x4  =  b25 
#> 1*x1 + 1*x2 + 1*x3 + 1*x4  =  b26 
#> 1*x1 + 0*x2 + 1*x3 + 0*x4  =  b27 
#> 1*x1 + 1*x2 + 1*x3 + 1*x4  =  b28 
#> 1*x1 + 0*x2 + 1*x3 + 0*x4  =  b29 
#> 1*x1 + 0*x2 + 1*x3 + 0*x4  =  b30 
#> 1*x1 + 0*x2 + 1*x3 + 0*x4  =  b31 
#> 1*x1 + 1*x2 + 1*x3 + 1*x4  =  b32 
  showEqn(twoway_int, reduce=TRUE)
#> 1*x1 + 0*x2 + 1*x3 + 0*x4  =  b1 
#> 1*x1 + 1*x2 + 1*x3 + 1*x4  =  b2 
#> 1*x1 + 1*x2 + 0*x3 + 0*x4  =  b3 
#> 1*x1 + 0*x2 + 0*x3 + 0*x4  =  b4 
  showEqn(twoway_int, reduce=TRUE, simplify=TRUE)
#> x1      + x3       =  b1 
#> x1 + x2 + x3 + x4  =  b2 
#> x1 + x2            =  b3 
#> x1                 =  b4 

  # Piece-wise linear regression
  x <- c(1:10, 13:22)
  y <- numeric(20)
  y[1:10] <- 20:11 + rnorm(10, 0, 1.5)
  y[11:20] <- seq(11, 15, len=10) + rnorm(10, 0, 1.5)
  plot(x, y, pch = 16)

  x2 <- as.numeric(x > 10)
  mod <- lm(y ~ x + I((x - 10) * x2))
  summary(mod)
#> 
#> Call:
#> lm(formula = y ~ x + I((x - 10) * x2))
#> 
#> Residuals:
#>     Min      1Q  Median      3Q     Max 
#> -2.4470 -0.6140 -0.4304  1.0993  2.4990 
#> 
#> Coefficients:
#>                  Estimate Std. Error t value Pr(>|t|)    
#> (Intercept)       20.9943     0.9522  22.048 6.05e-14 ***
#> x                 -0.9731     0.1412  -6.891 2.61e-06 ***
#> I((x - 10) * x2)   1.3166     0.2203   5.977 1.50e-05 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> Residual standard error: 1.45 on 17 degrees of freedom
#> Multiple R-squared:  0.7444,	Adjusted R-squared:  0.7143 
#> F-statistic: 24.75 on 2 and 17 DF,  p-value: 9.223e-06
#> 
  lines(x, fitted(mod))

  showEqn(mod)
#> 1*x1  + 1*x2  + 0*x3  =   b1 
#> 1*x1  + 2*x2  + 0*x3  =   b2 
#> 1*x1  + 3*x2  + 0*x3  =   b3 
#> 1*x1  + 4*x2  + 0*x3  =   b4 
#> 1*x1  + 5*x2  + 0*x3  =   b5 
#> 1*x1  + 6*x2  + 0*x3  =   b6 
#> 1*x1  + 7*x2  + 0*x3  =   b7 
#> 1*x1  + 8*x2  + 0*x3  =   b8 
#> 1*x1  + 9*x2  + 0*x3  =   b9 
#> 1*x1 + 10*x2  + 0*x3  =  b10 
#> 1*x1 + 13*x2  + 3*x3  =  b11 
#> 1*x1 + 14*x2  + 4*x3  =  b12 
#> 1*x1 + 15*x2  + 5*x3  =  b13 
#> 1*x1 + 16*x2  + 6*x3  =  b14 
#> 1*x1 + 17*x2  + 7*x3  =  b15 
#> 1*x1 + 18*x2  + 8*x3  =  b16 
#> 1*x1 + 19*x2  + 9*x3  =  b17 
#> 1*x1 + 20*x2 + 10*x3  =  b18 
#> 1*x1 + 21*x2 + 11*x3  =  b19 
#> 1*x1 + 22*x2 + 12*x3  =  b20 
  showEqn(mod, vars=round(coef(mod),2))
#> 1*20.99  + 1*-0.97  + 0*1.32  =   b1 
#> 1*20.99  + 2*-0.97  + 0*1.32  =   b2 
#> 1*20.99  + 3*-0.97  + 0*1.32  =   b3 
#> 1*20.99  + 4*-0.97  + 0*1.32  =   b4 
#> 1*20.99  + 5*-0.97  + 0*1.32  =   b5 
#> 1*20.99  + 6*-0.97  + 0*1.32  =   b6 
#> 1*20.99  + 7*-0.97  + 0*1.32  =   b7 
#> 1*20.99  + 8*-0.97  + 0*1.32  =   b8 
#> 1*20.99  + 9*-0.97  + 0*1.32  =   b9 
#> 1*20.99 + 10*-0.97  + 0*1.32  =  b10 
#> 1*20.99 + 13*-0.97  + 3*1.32  =  b11 
#> 1*20.99 + 14*-0.97  + 4*1.32  =  b12 
#> 1*20.99 + 15*-0.97  + 5*1.32  =  b13 
#> 1*20.99 + 16*-0.97  + 6*1.32  =  b14 
#> 1*20.99 + 17*-0.97  + 7*1.32  =  b15 
#> 1*20.99 + 18*-0.97  + 8*1.32  =  b16 
#> 1*20.99 + 19*-0.97  + 9*1.32  =  b17 
#> 1*20.99 + 20*-0.97 + 10*1.32  =  b18 
#> 1*20.99 + 21*-0.97 + 11*1.32  =  b19 
#> 1*20.99 + 22*-0.97 + 12*1.32  =  b20 
  showEqn(mod, simplify=TRUE)
#> x1    + x2          =   b1 
#> x1  + 2*x2          =   b2 
#> x1  + 3*x2          =   b3 
#> x1  + 4*x2          =   b4 
#> x1  + 5*x2          =   b5 
#> x1  + 6*x2          =   b6 
#> x1  + 7*x2          =   b7 
#> x1  + 8*x2          =   b8 
#> x1  + 9*x2          =   b9 
#> x1 + 10*x2          =  b10 
#> x1 + 13*x2  + 3*x3  =  b11 
#> x1 + 14*x2  + 4*x3  =  b12 
#> x1 + 15*x2  + 5*x3  =  b13 
#> x1 + 16*x2  + 6*x3  =  b14 
#> x1 + 17*x2  + 7*x3  =  b15 
#> x1 + 18*x2  + 8*x3  =  b16 
#> x1 + 19*x2  + 9*x3  =  b17 
#> x1 + 20*x2 + 10*x3  =  b18 
#> x1 + 21*x2 + 11*x3  =  b19 
#> x1 + 22*x2 + 12*x3  =  b20