bpca Overview

Introduction

bpca is an S3-based package for principal component biplot analysis. It supports:

This vignette presents a practical end-to-end workflow.

Load Package and Data

library(bpca)
data(gabriel1971)
data(ontario)

gabriel1971 is a classic biplot matrix and works well for reproducible examples.

2D Biplot: Core Workflow

bp2 <- bpca(gabriel1971,
            d=1:2)
class(bp2)
#> [1] "bpca.2d" "bpca"    "list"
bp2$number
#> [1] 1 2
round(bp2$importance, 3)
#>         explained
#> general     0.973
#> partial     0.973

Key returned components include:

names(bp2)
#> [1] "call"         "eigenvalues"  "eigenvectors" "number"       "importance"  
#> [6] "coord"        "var.rb"       "var.rd"
str(bp2$coord)
#> List of 2
#>  $ objects  : num [1:8, 1:8] 3.976 2.593 -2.193 1.746 -0.929 ...
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr [1:8] "toilet" "kitchen" "bath" "eletricity" ...
#>   .. ..$ : chr [1:8] "PC1" "PC2" "PC3" "PC4" ...
#>  $ variables: num [1:9, 1:8] 2.58 2.6 2.58 2.6 2.43 ...
#>   ..- attr(*, "dimnames")=List of 2
#>   .. ..$ : chr [1:9] "CRISTIAN" "ARMENIAN" "JEWISH" "MOSLEM" ...
#>   .. ..$ : chr [1:8] "PC1" "PC2" "PC3" "PC4" ...

Summary Output

summary(bp2)
#> Eigenvalue(s) :
#> [1] 7.627198e+00 1.771676e+00 1.096260e+00 5.064330e-01 3.456395e-01
#> [6] 3.150429e-01 1.001889e-01 5.766751e-16
#> 
#> Considered on reduction :
#> [1] 7.627198 1.771676
#> 
#> Variance retained by each :
#> [1] 0.92339915 0.04982279
#> 
#> Cumulative variance retained :
#> [1] 0.9233991 0.9732219
#> 
#> Prop. of total variance retained :
#> [1] 0.973
summary(bp2,
        presentation=TRUE)
#>  Eigenvalue(s):               7.627198 1.771676 1.09626 0.506433 0.3456395 0.3150429 0.1001889 5.766751e-16
#>   - Considered on reduction:      7.627198 1.771676
#>   - Variance retained by each:        0.9233991 0.04982279
#>   - Cumulative variance retained:     0.9233991 0.9732219
#>   - Prop. of total variance retained:     0.973

Factorization Methods

methods <- c("hj", "sqrt", "jk", "gh")
retained <- sapply(
  methods,
  function(m) {
    bp <- bpca(gabriel1971,
               method=m,
               d=1:2)
    as.numeric(bp$importance["general", "explained"])
  }
)
retained
#>    hj  sqrt    jk    gh 
#> 0.973 0.973 0.973 0.973

The retained variance can be similar across methods, but geometric interpretation differs.

Representation Quality Diagnostics

var.rb stores projected correlations among variables under the selected biplot reduction.

bp2_q <- bpca(gabriel1971,
              d=1:2,
              var.rb=TRUE)
round(bp2_q$var.rb, 2)
#>          CRISTIAN ARMENIAN JEWISH MOSLEM MODERN.1 MODERN.2 OTHER.1 OTHER.2  RUR
#> CRISTIAN     1.00     1.00   1.00   1.00     0.88     0.87    0.98    1.00 0.99
#> ARMENIAN     1.00     1.00   1.00   1.00     0.87     0.86    0.98    1.00 0.99
#> JEWISH       1.00     1.00   1.00   1.00     0.83     0.82    0.97    0.99 1.00
#> MOSLEM       1.00     1.00   1.00   1.00     0.86     0.85    0.98    1.00 1.00
#> MODERN.1     0.88     0.87   0.83   0.86     1.00     1.00    0.95    0.90 0.80
#> MODERN.2     0.87     0.86   0.82   0.85     1.00     1.00    0.94    0.89 0.79
#> OTHER.1      0.98     0.98   0.97   0.98     0.95     0.94    1.00    0.99 0.95
#> OTHER.2      1.00     1.00   0.99   1.00     0.90     0.89    0.99    1.00 0.98
#> RUR          0.99     0.99   1.00   1.00     0.80     0.79    0.95    0.98 1.00

qbpca() compares observed vs projected correlations in vectorized form.

q2 <- qbpca(gabriel1971,
            bp2_q)
head(q2)
#>                             obs    var.rb
#> CRISTIAN vs. ARMENIAN 0.9973894 0.9999397
#> CRISTIAN vs. JEWISH   0.9561588 0.9961640
#> CRISTIAN vs. MOSLEM   0.9857920 0.9991587
#> CRISTIAN vs. MODERN.1 0.8665372 0.8773237
#> CRISTIAN vs. MODERN.2 0.8216573 0.8674140
#> CRISTIAN vs. OTHER.1  0.9520075 0.9849207

var.rd highlights poorly represented variable correlations for a chosen threshold (limit).

bp2_rd <- bpca(gabriel1971,
               d=1:2,
               var.rb=TRUE,
               var.rd=TRUE,
               limit=3)
bp2_rd$var.rd
#>          CRISTIAN ARMENIAN JEWISH MOSLEM MODERN.1 MODERN.2 OTHER.1 OTHER.2 RUR
#> CRISTIAN        -               *                        *       *       *   *
#> ARMENIAN                 -      *                        *                   *
#> JEWISH          *        *      -                                            *
#> MOSLEM                                 -                                     *
#> MODERN.1                                        -                            *
#> MODERN.2        *        *                               -                    
#> OTHER.1         *                                                -           *
#> OTHER.2         *                                                        -   *
#> RUR             *        *      *      *        *                *       *   -

3D Workflow

bp3 <- bpca(gabriel1971,
            d=1:3,
            var.rb=TRUE)
bp3$number
#> [1] 1 2 3
round(bp3$importance, 3)
#>         explained
#> general     0.992
#> partial     0.992

Plot Types and Examples

The plot.bpca.2d method supports several analysis-oriented views via type:

Examples (kept as non-evaluated chunks to keep vignette deterministic):

# Basic 2D
plot(bp2)

# Evaluate one object
plot(bpca(ontario),
     type="eo",
     obj.id=7)

# Evaluate one variable
plot(bpca(ontario),
     type="ev",
     var.id="E7")

# Compare two objects
plot(bpca(ontario),
     type="co",
     obj.id=c("g7", "g13"))

3D rendering can be static (scatterplot3d) or interactive (rgl):

# Static 3D
plot(bp3)

# Interactive 3D
plot(bp3,
     rgl.use=TRUE)

Tabular Reporting with xtable

The package provides an xtable method for bpca objects.

if (requireNamespace("xtable", quietly=TRUE)) {
  tbl <- xtable::xtable(bp2)
  tbl[1:6, , drop=FALSE]
}
#> % latex table generated in R 4.7.0 by xtable 1.8-8 package
#> % Mon May 11 12:17:21 2026
#> \begin{table}[ht]
#> \centering
#> \begin{tabular}{lrrr}
#>   \hline
#>   &&\multicolumn{2}{c}{Eigenvectors\_MOSLEM} \\ \cline{3-4}
#>  &&  PC1 $(\lambda_1=0.34)$& PC2 $(\lambda_2=0.21)$ \\ 
#>   \hline 
#>  \multirow{3}{*}{Eigenvectors}&CRISTIAN&0.34&0.15 \\ 
#> &ARMENIAN & 0.34 & 0.17 \\ 
#>   &JEWISH & 0.34 & 0.28 \\ 
#>    \hline
#> &Eigenvectors\_MODERN.1 & 0.32 & -0.58 \\ 
#>   &Eigenvectors\_MODERN.2 & 0.31 & -0.60 \\ 
#>    \hline
#> \end{tabular}
#> \end{table}

Use print() (S3) so the xtable.bpca formatter runs; xtable::print.xtable() does not dispatch to it.

HTML (this vignette)

For HTML output (including this html_vignette), pass type="html". The chunk must use results='asis' so the table is inserted as raw HTML.

if (requireNamespace("xtable",
                     quietly=TRUE)) {
  tbl <- xtable::xtable(bp2)
  print(tbl,
        type="html")
}
PC1 (λ1=7.63) PC2 (λ2=1.77)
CRISTIAN 0.34 0.15
ARMENIAN 0.34 0.17
JEWISH 0.34 0.28
MOSLEM 0.34 0.21
MODERN.1 0.32 -0.58
MODERN.2 0.31 -0.60
OTHER.1 0.35 -0.11
OTHER.2 0.34 0.07
RUR 0.32 0.34
Variance retained 0.92 0.05
Variance accumulated 0.92 0.97

LaTeX (PDF reports)

To generate the biplot-style LaTeX table (e.g. pdf_document or Sweave), use the default type and call print():

tbl <- xtable::xtable(bp2,
                      caption="Biplot summary",
                      label="tab:bp2")
rn <- rownames(tbl)
idx_retained <- which(rn == "Variance retained")
hlines <- c(-1, 0, nrow(tbl) - 1L)
if (length(idx_retained) == 1L && idx_retained > 1L) {
  hlines <- c(hlines, idx_retained - 1L)
}
hlines <- sort(unique(hlines))
print(tbl,
      hline.after=hlines)

Notes