nda constructs interpretable latent variables from
communities in squared-association networks. It supports unsupervised
dimensionality reduction with ndr() and supervised
modelling with ndrlm().
Version 0.3.0 adds faster and safer association calculations, sparse and parallel workflows, fixed memberships, inference and bootstrap diagnostics, new centrality definitions, prediction methods, configurable graphics, and ordinary least squares, ridge, elastic-net, and LOESS response engines.
Install the development version from GitHub:
remotes::install_github("kzst/nda")
library(nda)ndr()ndr():
fit <- ndr(
swiss,
cor_method = "spearman",
cor_type = "full",
centrality = "pagerank",
min_comm = 2,
seed = 42
)
fit
summary(fit)
round(fit$loadings, 3)
# Score new observations with the training transformation.
predict(fit, swiss[1:5, , drop = FALSE])Network and biplot functions return printable objects. Assignment is silent; print the object to render it.
network <- plot(
fit,
interactive = FALSE,
show_weights = TRUE,
shape = "automatic"
)
network
# The same visual grammar as an embedded interactive HTML widget.
interactive_network <- plot(fit, interactive = TRUE, show_weights = TRUE)
interactive_network
score_plot <- biplot(fit, view_3D = FALSE, interactive = FALSE)
score_plotCommunity membership is shown with a light qualitative node-colour palette. Indicators use one common rectangular shape by default; positive and negative associations use green and red edges, and absolute association controls edge width. Shapes, colours, line types, and the minimum/maximum width remain configurable.
covar = TRUE accepts an arbitrary square similarity
matrix. For example, NDR can cluster observations from normalized
Euclidean similarities:
z <- scale(swiss)
d <- as.matrix(dist(z))
similarity <- 1 - d / max(d)
cluster_fit <- ndr(similarity, covar = TRUE, seed = 42)
table(cluster_fit$membership)Important options include:
ndrlm()ndrlm() connects original or NDA-reduced predictors to
original or NDA-reduced responses. Set latents to
"none", "in", "out", or
"both".
The example below uses the two-community latent input structure from
the published low-sample-size mtcars application:
X <- mtcars[, setdiff(names(mtcars), "mpg")]
Y <- mtcars["mpg"]
membership <- c(
cyl = 1, disp = 2, hp = 1, drat = 2, wt = 2,
qsec = 1, vs = 1, am = 2, gear = 2, carb = 1
)
model <- ndrlm(
Y,
X,
latents = "in",
optimize = FALSE,
regression = "lm",
membership.X = membership,
seed = 42
)
summary(model)
predict(model, X[1:5, , drop = FALSE])
head(fitted(model))
head(residuals(model))For regression = "lm", each model$fits[[i]]
is a genuine lm object and can be used directly with
summary(), AIC(), BIC(), and
lm.beta::lm.beta().
inherits(model$fits[[1]], "lm")
summary(model$fits[[1]])Ridge and elastic net use glmnet and retain NDRLM engine
wrappers:
ridge <- ndrlm(
Y,
X,
latents = "none",
optimize = FALSE,
regression = "ridge",
lambda = 0.1
)
predict(ridge, X[1:5, , drop = FALSE])The package methods also accept legacy direct lm fits
and early 0.3.0 wrapped lm fits. For engine-independent
code, use summary(), predict(),
fitted(), residuals(), and plot()
on the enclosing ndrlm object.
static_paths <- plot(
model,
interactive = FALSE,
shape = "automatic"
)
static_paths
interactive_paths <- plot(
model,
interactive = TRUE,
show_edge_labels = TRUE
)
interactive_pathsObserved variables are rectangles and latent variables are circles.
Each latent variable and its indicators share one light community
colour. Positive paths are green, negative paths are red, and absolute
standardized coefficient or loading magnitude controls width within its
edge role. The plot computes standardized structural coefficients for
ordinary linear, ridge, and elastic-net regression from the complete
training observations; use standardized.paths = FALSE only
when raw coefficients are required. Measurement links between observed
and latent variables are dashed; structural paths are solid. Latent
nodes are centred on their indicator groups, absent layers leave no
empty horizontal column, and the default node fills are slightly
translucent and lightened. Edge labels use a light background offset
from the path to avoid overwriting thick lines. For legacy unnamed fit
lists, the path target is recovered from the fitted response formula
before any original-variable fallback is considered; standardized
coefficients are reconstructed from the legacy fitted model.
Static plots use the package’s layered grid renderer by default. The
legacy igraph renderer remains available with
static.engine = "igraph". Both static and interactive
variants are printable objects, so the following pattern works with
screen and file devices:
p <- plot(model, interactive = FALSE) # no drawing during assignment
p # draw now
pdf("ndrlm-paths.pdf", width = 10, height = 6)
p
dev.off()Expensive NSGA-II optimization is optional:
optimized <- ndrlm(
Y,
X,
latents = "in",
regression = "lm",
target = "adj.r.square",
popsize = 20,
generations = 50,
restarts = 3,
seed = 42
)
plot(
optimized$NSGA_trace$evaluation,
optimized$NSGA_trace$best_target,
type = "s",
xlab = "Objective evaluation",
ylab = "Best target value"
)| Purpose | Functions |
|---|---|
| Structured example data | data_gen() |
| Global, row, or column scaling | normalize() |
| Distance covariance and correlation | dCov(), dCor() |
| Partial and semipartial distance correlation | pdCor(), spdCor() |
| KMO-based feature selection | fs.KMO() |
| Loading-based feature selection and iterative refitting | fs.dimred() |
The source package builds three official vignettes:
nda-function-tour: a visual tour of the package;ndr-workflow: the generalized NDR workflow;ndrlm-workflow: supervised latent-variable
regression.List or open them from an installed package with:
vignette(package = "nda")
vignette("nda-function-tour", package = "nda")
vignette("ndr-workflow", package = "nda")
vignette("ndrlm-workflow", package = "nda")seed whenever community detection, bootstrap
inference, or NSGA-II is involved.n_boot and optimization settings while
developing, then increase them for final analysis.sparsecalc = TRUE is useful after meaningful edge
thresholding.Kosztyan, Z. T., Kurbucz, M. T., and Katona, A. I. (2022). Network-based dimensionality reduction of high-dimensional, low-sample-size datasets. Knowledge-Based Systems, 109180. https://doi.org/10.1016/j.knosys.2022.109180
Kosztyan, Z. T., Katona, A. I., Kurbucz, M. T., and Lantos, Z. (2024). Generalized network-based dimensionality analysis. Expert Systems with Applications, 238, 121779. https://doi.org/10.1016/j.eswa.2023.121779
Zsolt T. Kosztyan, Marcell T. Kurbucz, Attila I. Katona, and Zahid Khan.