Skip to content

Commit

Permalink
Merge branch 'release-1.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
wleoncio committed Jan 9, 2025
2 parents 0010e79 + d56cd74 commit 8f8aa94
Show file tree
Hide file tree
Showing 24 changed files with 257 additions and 239 deletions.
2 changes: 2 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ CITATION.cff
aux/
^\.github$
^.*\.out
^cran-comments\.md$
^CRAN-SUBMISSION$
4 changes: 3 additions & 1 deletion .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
push:
branches: [main]
branches:
- main
- 'release-*'
pull_request:
branches: [main]

Expand Down
3 changes: 3 additions & 0 deletions CRAN-SUBMISSION
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Version: 1.0.0
Date: 2025-01-08 12:10:09 UTC
SHA: af2656631394df0b8771edb9d2ebcacdad682896
17 changes: 11 additions & 6 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: MADMMplasso
Title: Multi Variate Multi Response 'ADMM' with Interaction Effects
Version: 0.0.0.9024
Title: Multi Variate Multi Response ADMM with Interaction Effects
Version: 1.0.0
Authors@R:
c(
person(
Expand All @@ -25,9 +25,13 @@ Authors@R:
role = "aut"
)
)
Description: This system allows one to model a multi response problem
that has correlation among the responses and also has main and interaction
effects among the covariates. The implementation is based on the methodology
Description: This system allows one to model a multi-variate, multi-response
problem with interaction effects. It combines the usual squared error loss
for the multi-response problem with some penalty terms to encourage
responses that correlate to form groups and also allow for modeling main and
interaction effects that exit within the covariates.
The optimization method employed is the Alternating Direction Method of
Multipliers (ADMM). The implementation is based on the methodology
presented on Quachie Asenso, T., & Zucknick, M. (2023)
<doi:10.48550/arXiv.2303.11155>.
Imports:
Expand All @@ -46,10 +50,11 @@ Imports:
LinkingTo: Rcpp, RcppArmadillo
Suggests:
testthat (>= 3.0.0),
pracma,
lintr
License: GPL-3
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.2
Config/testthat/edition: 3
Date: 2025-01-08
Language: en-GB
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# MADMMplasso 1.0.0

* Initial CRAN submission.
2 changes: 1 addition & 1 deletion R/MADMMplasso.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#' @param rho the Lagrange variable for the ADMM. This value is updated during the ADMM call based on a certain condition.
#' @param e.abs absolute error for the ADMM
#' @param e.rel relative error for the ADMM
#' @param gg penalty term for the tree structure. This is a 2x2 matrix values in the first row representing the maximum to the minimum values for lambda_1 and the second row representing the maximum to the minimum values for lambda_2. In the current setting, we set both maximum and the minimum to be same because cross validation is not carried across the lambda_1 and lambda_2. However, setting different values will work during the model fit.
#' @param gg penalty term for the tree structure. This is a 2×2 matrix values in the first row representing the maximum to the minimum values for lambda_1 and the second row representing the maximum to the minimum values for lambda_2. In the current setting, we set both maximum and the minimum to be same because cross validation is not carried across the lambda_1 and lambda_2. However, setting different values will work during the model fit.
#' @param my_lambda user specified lambda_3 values
#' @param lambda_min the smallest value for lambda_3 , as a fraction of max(lambda_3), the (data derived (lammax)) entry value (i.e. the smallest value for which all coefficients are zero)
#' @param max_it maximum number of iterations in loop for one lambda during the ADMM optimization
Expand Down
10 changes: 5 additions & 5 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#' @param X n by p matrix of predictors
#' @param Z n by nz matrix of modifying variables. The elements of z
#' may represent quantitative or categorical variables, or a mixture of the two.
#' Categorical varables should be coded by 0-1 dummy variables: for a k-level
#' Categorical variables should be coded by 0-1 dummy variables: for a k-level
#' variable, one can use either k or k-1 dummy variables.
#' @param beta0 a vector of length ncol(y) of estimated beta_0 coefficients
#' @param theta0 matrix of the initial theta_0 coefficients ncol(Z) by ncol(y)
Expand All @@ -18,10 +18,10 @@
#' @param XtY a matrix formed by multiplying the transpose of X by y.
#' @param y N by D matrix of responses. The X and Z variables are centered in the function. We recommend that X and Z also be standardized before the call
#' @param N nrow(X)
#' @param e_abs absolute error for the admm. This is included int the call of MADMMplasso.
#' @param e_rel relative error for the admm. This is included int the call of MADMMplasso.
#' @param e_abs absolute error for the ADMM. This is included int the call of MADMMplasso.
#' @param e_rel relative error for the ADMM. This is included int the call of MADMMplasso.
#' @param alpha mixing parameter, usually obtained from the MADMMplasso call. When the goal is to include more interactions, alpha should be very small and vice versa.
#' @param lambda a vector lambda_3 values for the admm call with length ncol(y). This is usually calculated in the MADMMplasso call. In our current setting, we use the same the lambda_3 value for all responses.
#' @param lambda a vector lambda_3 values for the ADMM call with length ncol(y). This is usually calculated in the MADMMplasso call. In our current setting, we use the same the lambda_3 value for all responses.
#' @param alph an overrelaxation parameter in \[1, 1.8\], usually obtained from the MADMMplasso call.
#' @param svd_w_tu the transpose of the U matrix from the SVD of W_hat
#' @param svd_w_tv the transpose of the V matrix from the SVD of W_hat
Expand All @@ -31,7 +31,7 @@
#' The easy way to obtain this is by using the function (tree_parms) which gives a default clustering.
#' However, user decide on a specific structure and then input a tree that follows such structure.
#' @param my_print Should information form each ADMM iteration be printed along the way? Default TRUE. This prints the dual and primal residuals
#' @param gg penalty terms for the tree structure for lambda_1 and lambda_2 for the admm call.
#' @param gg penalty terms for the tree structure for lambda_1 and lambda_2 for the ADMM call.
#' @return predicted values for the ADMM part
#' @description This function fits a multi-response pliable lasso model over a path of regularization values.
#' @export
Expand Down
2 changes: 1 addition & 1 deletion R/admm_MADMMplasso.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#' @param N nrow(X)
#' @param svd.w singular value decomposition of W
#' @param invmat A list of length ncol(y), each containing the C_d part of equation 32 in the paper
#' @param gg penalty terms for the tree structure for lambda_1 and lambda_2 for the admm call.
#' @param gg penalty terms for the tree structure for lambda_1 and lambda_2 for the ADMM call.
#' @return predicted values for the ADMM part

#' beta0: estimated beta_0 coefficients having a size of 1 by ncol(y)
Expand Down
2 changes: 1 addition & 1 deletion R/cv_MADMMplasso.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ cv_MADMMplasso <- function(fit, nfolds, X, Z, y, alpha = 0.5, lambda = fit$Lambd
nfolds <- length(table(foldid))

for (ii in 1:nfolds) {
cat("fold,", ii)
if (my_print) cat("fold,", ii)
oo <- foldid == ii

ggg[[ii]] <- MADMMplasso(X = X[!oo, , drop = FALSE], Z = Z[!oo, , drop = FALSE], y = y[!oo, , drop = FALSE], alpha = alpha, my_lambda = lambda, lambda_min = 0.01, max_it = max_it, e.abs = e.abs, e.rel = e.rel, nlambda = length(lambda[, 1]), rho = rho, tree = TT, my_print = my_print, alph = alph, pal = pal, gg = gg, tol = tol, cl = cl, legacy)
Expand Down
3 changes: 1 addition & 2 deletions R/predict.MADMMplasso.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
#' @param y N by D matrix of responses.
#' @param lambda values of lambda at which predictions are desired. If NULL (default), the path of lambda values from the fitted model. are used. If lambda is not NULL, the predictions are made at the closest values to lambda in the lambda path from the fitted model
#' @param ... additional arguments to the generic \code{predict()} method

#' @return predicted values
#' @return predicted values
#' @export
predict.MADMMplasso <- function(object, X, Z, y, lambda = NULL, ...) {
lambda.arg <- lambda
Expand Down
2 changes: 1 addition & 1 deletion R/tree_parms.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#' @param y N by D matrix of response variables
#' @param h is the tree cut off
#' @return A trained tree with the following components:
#' Tree: the tree matrix stored in 1's and 0's
#' Tree: the tree matrix stored in 1s and 0s
#' Tw: tree weights associated with the tree matrix. Each weight corresponds to a row in the tree matrix.
#' h_clust: Summary of the hclust call
#' y.colnames: names of the response
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

Multi variate multi-response 'ADMM' with interaction effects combines the usual squared error loss for the mult-response problem with some penalty terms to encourage responses that correlate to form groups and also allow for modeling main and interaction effects that exit within the covariates.

The method can be powperful in situations where one assumes that;
1. certain factors influence the main covariate seperatly and aims to include these fatcors as modifying varibles to the main covariate.
The method can be powerful in situations where one assumes that;
1. certain factors influence the main covariate separately and aims to include these factors as modifying variables to the main covariate.
2. There exists some form of grouping within the responses and want to include this information. We assume that the responses form overlapping groups that follows a certain hierarchy.
A typical example is when one wants to model drug response for multiple drugs and assumes that some of the drugs share certain properties in common, for example drug target and chemical compounds and aims to include this information to improve prediction and also aim to predict which drug could be suitable for which patient (given a particular disease). The various diseases under study could be the modifying variable.

Expand Down Expand Up @@ -65,7 +65,7 @@ TT <- tree_parms(y)
plot(TT$h_clust)
```

![githubb](https://github.com/ocbe-uio/MADMMplasso/assets/85598983/1a843b46-7154-405c-8db6-cec5b7a0982d)
![github](https://github.com/ocbe-uio/MADMMplasso/assets/85598983/1a843b46-7154-405c-8db6-cec5b7a0982d)

```r
gg1 <- matrix(0,2,2)
Expand Down
13 changes: 13 additions & 0 deletions cran-comments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Resubmission of 1.0.0, addressing all points from reviewer. Namely:

- Single quotes around ADMM have been removed
- ADMM acronym has been explained in the package description
- \value tag has been added to predict.MADMMplasso()
- Wrapped examples have been unwrapped
- cat() calls have been conditioned to a verbose argument

## R CMD check results

0 errors | 0 warnings | 1 note

* This is a new release.
6 changes: 3 additions & 3 deletions inst/examples/MADMMplasso_example.R
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ tol <- 1E-3
fit <- MADMMplasso(
X, Z, y,
alpha = alpha, my_lambda = matrix(rep(0.2, ncol(y)), 1),
lambda_min = 0.001, max_it = 5000, e.abs = e.abs, e.rel = e.rel, maxgrid = nlambda,
nlambda = nlambda, rho = 5, tree = TT, my_print = FALSE, alph = TRUE,
pal = TRUE, gg = gg1, tol = tol, cl = 6
lambda_min = 0.001, max_it = 1000, e.abs = e.abs, e.rel = e.rel,
maxgrid = nlambda, nlambda = nlambda, rho = 5, tree = TT, my_print = FALSE,
alph = TRUE, gg = gg1, tol = tol, cl = 2L
)
176 changes: 85 additions & 91 deletions inst/examples/cv_MADMMplasso_example.R
Original file line number Diff line number Diff line change
@@ -1,97 +1,91 @@
# nolint start: indentation_linter
\dontrun{
# Train the model
# generate some data
set.seed(1235)
N <- 100
p <- 50
nz <- 4
K <- nz
X <- matrix(rnorm(n = N * p), nrow = N, ncol = p)
mx <- colMeans(X)
sx <- sqrt(apply(X, 2, var))
X <- scale(X, mx, sx)
X <- matrix(as.numeric(X), N, p)
Z <- matrix(rnorm(N * nz), N, nz)
mz <- colMeans(Z)
sz <- sqrt(apply(Z, 2, var))
Z <- scale(Z, mz, sz)
beta_1 <- rep(x = 0, times = p)
beta_2 <- rep(x = 0, times = p)
beta_3 <- rep(x = 0, times = p)
beta_4 <- rep(x = 0, times = p)
beta_5 <- rep(x = 0, times = p)
beta_6 <- rep(x = 0, times = p)
# Train the model
# generate some data
set.seed(1235)
N <- 100
p <- 50
nz <- 4
K <- nz
X <- matrix(rnorm(n = N * p), nrow = N, ncol = p)
mx <- colMeans(X)
sx <- sqrt(apply(X, 2, var))
X <- scale(X, mx, sx)
X <- matrix(as.numeric(X), N, p)
Z <- matrix(rnorm(N * nz), N, nz)
mz <- colMeans(Z)
sz <- sqrt(apply(Z, 2, var))
Z <- scale(Z, mz, sz)
beta_1 <- rep(x = 0, times = p)
beta_2 <- rep(x = 0, times = p)
beta_3 <- rep(x = 0, times = p)
beta_4 <- rep(x = 0, times = p)
beta_5 <- rep(x = 0, times = p)
beta_6 <- rep(x = 0, times = p)

beta_1[1:5] <- c(2, 2, 2, 2, 2)
beta_2[1:5] <- c(2, 2, 2, 2, 2)
beta_3[6:10] <- c(2, 2, 2, -2, -2)
beta_4[6:10] <- c(2, 2, 2, -2, -2)
beta_5[11:15] <- c(-2, -2, -2, -2, -2)
beta_6[11:15] <- c(-2, -2, -2, -2, -2)
beta_1[1:5] <- c(2, 2, 2, 2, 2)
beta_2[1:5] <- c(2, 2, 2, 2, 2)
beta_3[6:10] <- c(2, 2, 2, -2, -2)
beta_4[6:10] <- c(2, 2, 2, -2, -2)
beta_5[11:15] <- c(-2, -2, -2, -2, -2)
beta_6[11:15] <- c(-2, -2, -2, -2, -2)

Beta <- cbind(beta_1, beta_2, beta_3, beta_4, beta_5, beta_6)
colnames(Beta) <- c(1:6)
Beta <- cbind(beta_1, beta_2, beta_3, beta_4, beta_5, beta_6)
colnames(Beta) <- c(1:6)

Check warning on line 32 in inst/examples/cv_MADMMplasso_example.R

View workflow job for this annotation

GitHub Actions / lint

file=inst/examples/cv_MADMMplasso_example.R,line=32,col=19,[unnecessary_concatenation_linter] Unneeded concatenation of a constant. Remove the "c" call.

theta <- array(0, c(p, K, 6))
theta[1, 1, 1] <- 2
theta[3, 2, 1] <- 2
theta[4, 3, 1] <- -2
theta[5, 4, 1] <- -2
theta[1, 1, 2] <- 2
theta[3, 2, 2] <- 2
theta[4, 3, 2] <- -2
theta[5, 4, 2] <- -2
theta[6, 1, 3] <- 2
theta[8, 2, 3] <- 2
theta[9, 3, 3] <- -2
theta[10, 4, 3] <- -2
theta[6, 1, 4] <- 2
theta[8, 2, 4] <- 2
theta[9, 3, 4] <- -2
theta[10, 4, 4] <- -2
theta[11, 1, 5] <- 2
theta[13, 2, 5] <- 2
theta[14, 3, 5] <- -2
theta[15, 4, 5] <- -2
theta[11, 1, 6] <- 2
theta[13, 2, 6] <- 2
theta[14, 3, 6] <- -2
theta[15, 4, 6] <- -2
theta <- array(0, c(p, K, 6))
theta[1, 1, 1] <- 2
theta[3, 2, 1] <- 2
theta[4, 3, 1] <- -2
theta[5, 4, 1] <- -2
theta[1, 1, 2] <- 2
theta[3, 2, 2] <- 2
theta[4, 3, 2] <- -2
theta[5, 4, 2] <- -2
theta[6, 1, 3] <- 2
theta[8, 2, 3] <- 2
theta[9, 3, 3] <- -2
theta[10, 4, 3] <- -2
theta[6, 1, 4] <- 2
theta[8, 2, 4] <- 2
theta[9, 3, 4] <- -2
theta[10, 4, 4] <- -2
theta[11, 1, 5] <- 2
theta[13, 2, 5] <- 2
theta[14, 3, 5] <- -2
theta[15, 4, 5] <- -2
theta[11, 1, 6] <- 2
theta[13, 2, 6] <- 2
theta[14, 3, 6] <- -2
theta[15, 4, 6] <- -2

pliable = matrix(0,N,6)
for (e in 1:6) {
pliable[,e]<- compute_pliable(X, Z, theta[,,e])
}

esd<-diag(6)
e<-MASS::mvrnorm(N,mu=rep(0,6),Sigma=esd)
y_train<-X%*%Beta+pliable+e
y=y_train
pliable <- matrix(0, N, 6)
for (e in 1:6) {
pliable[, e] <- compute_pliable(X, Z, theta[, , e])
}

colnames(y)<- c( paste("y",1:(ncol(y)),sep = "") )
TT=tree_parms(y)
plot(TT$h_clust)
gg1=matrix(0,2,2)
gg1[1,]<-c(0.02,0.02)
gg1[2,]<-c(0.02,0.02)
nlambda = 50
e.abs=1E-4
e.rel=1E-2
alpha=.2
tol=1E-3
fit <- MADMMplasso(
X, Z, y, alpha=alpha, my_lambda=NULL, lambda_min=0.001, max_it=5000,
e.abs=e.abs, e.rel=e.rel, maxgrid=50, nlambda=nlambda, rho=5,tree=TT,
my_print=FALSE, alph=1, parallel=FALSE, pal=TRUE, gg=gg1, tol=tol, cl=6
)
gg1=fit$gg
esd <- diag(6)
e <- MASS::mvrnorm(N, mu = rep(0, 6), Sigma = esd)
y_train <- X %*% Beta + pliable + e
y <- y_train

cv_admp <- cv_MADMMplasso(
fit, nfolds=5, X, Z, y, alpha=alpha, lambda=fit$Lambdas, max_it=5000,
e.abs=e.abs, e.rel=e.rel, nlambda, rho=5, my_print=FALSE, alph=1,
foldid=NULL, parallel=FALSE, pal=TRUE, gg=gg1, TT=TT, tol=tol
)
plot(cv_admp)
}
# nolint end: indentation_linter
colnames(y) <- c(paste("y", 1:(ncol(y)), sep = ""))

Check warning on line 70 in inst/examples/cv_MADMMplasso_example.R

View workflow job for this annotation

GitHub Actions / lint

file=inst/examples/cv_MADMMplasso_example.R,line=70,col=18,[paste_linter] paste0(...) is better than paste(..., sep = "").
TT <- tree_parms(y)
plot(TT$h_clust)
gg1 <- matrix(0, 2, 2)
gg1[1, ] <- c(0.02, 0.02)
gg1[2, ] <- c(0.02, 0.02)
nlambda <- 3
e.abs <- 1E-3
e.rel <- 1E-1
alpha <- .2

Check warning on line 79 in inst/examples/cv_MADMMplasso_example.R

View workflow job for this annotation

GitHub Actions / lint

file=inst/examples/cv_MADMMplasso_example.R,line=79,col=10,[numeric_leading_zero_linter] Include the leading zero for fractional numeric constants.
tol <- 1E-2
fit <- MADMMplasso(
X, Z, y, alpha = alpha, my_lambda = NULL, lambda_min = 0.001, max_it = 100,
e.abs = e.abs, e.rel = e.rel, maxgrid = nlambda, nlambda = nlambda, rho = 5,
tree = TT, my_print = FALSE, alph = 1, gg = gg1, tol = tol, cl = 2L
)
cv_admp <- cv_MADMMplasso(
fit, nfolds = 5, X, Z, y, alpha = alpha, lambda = fit$Lambdas, max_it = 100,
e.abs = e.abs, e.rel = e.rel, nlambda, rho = 5, my_print = FALSE, alph = 1,
foldid = NULL, gg = fit$gg, TT = TT, tol = tol
)
plot(cv_admp)
Loading

0 comments on commit 8f8aa94

Please sign in to comment.