Nothing
mmes <- function(fixed, random, rcov, data, W,
nIters=25, tolParConvLL = 1e-04,
tolParConvNorm = 1e-04, tolParInv = 1e-06,
naMethodX="exclude",
naMethodY="exclude",
returnParam=FALSE,
dateWarning=TRUE,
verbose=TRUE,
addScaleParam=NULL,
stepWeight=NULL, emWeight=NULL,
contrasts=NULL,
getPEV=TRUE, henderson=FALSE){
my.date <- "2025-07-01"
your.date <- Sys.Date()
## if your month is greater than my month you are outdated
if(dateWarning){
if (your.date > my.date) {
cat("Version out of date. Please update sommer to the newest version using:\ninstall.packages('sommer') in a new session\n Use the 'dateWarning' argument to disable the warning message.")
}
}
if(missing(data)){
data <- environment(fixed)
if(!missing(random)){
data2 <- environment(random)
}
nodata <-TRUE
cat("data argument not provided \n")
}else{nodata=FALSE; data <- as.data.frame(data)}
if(missing(rcov)){
rcov = as.formula("~units")
}
#################
## do the needed for naMethodY and naMethodX
dataor <- data
provdat <- subdata(data, fixed=fixed, na.method.Y = naMethodY,na.method.X=naMethodX)
data <- provdat$datar
nonMissing <- provdat$good
#################
data$units <- levels(as.factor(paste("u",1:nrow(data),sep="")))
#################
## get Y matrix
response <- strsplit(as.character(fixed[2]), split = "[+]")[[1]]
responsef <- as.formula(paste(response,"~1"))
mfna <- try(model.frame(responsef, data = data, na.action = na.pass), silent = TRUE)
if (is(mfna, "try-error") ) { # class(mfna) == "try-error"
stop("Please provide the 'data' argument for your specified variables.\nYou may be specifying some variables in your model not present in your dataset.", call. = FALSE)
}
mfna <- eval(mfna, data, parent.frame())
yvar <- sparse.model.matrix(as.formula(paste("~",response,"-1")),data)
nt <- ncol(yvar)
if(nt==1){colnames(yvar) <- response}
Vy <- var(yvar[,1])
# yvar <- scale(yvar)
#################
## get Zs and Ks
Z <- Ai <- theta <- thetaC <- thetaF <- sp <- list()
Zind <- numeric()
rTermsNames <- list()
counter <- 1
if(!missing(random)){ # if there's random effects
yuyu <- strsplit(as.character(random[2]), split = "[+]")[[1]] # random parts
rtermss <- apply(data.frame(yuyu),1,function(x){ # split random terms
strsplit(as.character((as.formula(paste("~",x)))[2]), split = "[+]")[[1]]
})
# print(rtermss)
for(u in 1:length(rtermss)){ # for each random effect u=1
checkvs <- intersect(all.names(as.formula(paste0("~",rtermss[u]))),c("vsm","spl2Dc")) # which(all.names(as.formula(paste0("~",rtermss[u]))) %in% c("vs","spl2Da","spl2Db")) # grep("vs\\(",rtermss[u])
if(length(checkvs)==0){ ## if this term is not in a variance structure put it inside
rtermss[u] <- paste("vsm( ism(",rtermss[u],") )")
}
ff <- eval(parse(text = rtermss[u]),data,parent.frame()) # evaluate the variance structure
Z <- c(Z, lapply(ff$Z, function(x){if(nrow(x) != length(nonMissing)){return(x[nonMissing,])}else{return(x)} }) )
# Z <- c(Z, ff$Z)
Ai <- c(Ai, ff$Gu)
theta[[u]] <- ff$theta
thetaC[[u]] <- ff$thetaC
thetaF[[u]] <- ff$thetaF
sp[[u]] <- ff$sp # rep(ff$sp,length(which(ff$thetaC > 0)))
Zind <- c(Zind, rep(u,length(ff$Z)))
checkvs <- numeric() # restart the check
## names for monitor
baseNames <- which( ff$thetaC > 0, arr.ind = TRUE)
s1 <- paste(rownames(ff$thetaC)[baseNames[,"row"]], colnames(ff$thetaC)[baseNames[,"col"]],sep = ":")
s2 <- paste(all.vars(as.formula(paste("~",rtermss[u]))),collapse=":")
rTermsNames[[u]] <- paste(s2,s1,sep=":")
counter <- counter + 1
}
}
# nEffects <- sum(unlist(lapply(Z,ncol)))
# nRecords <- length(yvar)
#################
## get Rs
yuyur <- strsplit(as.character(rcov[2]), split = "[+]")[[1]]
rcovtermss <- apply(data.frame(yuyur),1,function(x){
strsplit(as.character((as.formula(paste("~",x)))[2]), split = "[+]")[[1]]
})
S <- list()
Spartitions <- list()
for(u in 1:length(rcovtermss)){ # for each random effect
checkvs <- intersect(all.names(as.formula(paste0("~",rcovtermss[u]))),c("vsm","gvs","spl2Da","spl2Db")) # which(all.names(as.formula(paste0("~",rtermss[u]))) %in% c("vs","spl2Da","spl2Db")) # grep("vs\\(",rtermss[u])
if(length(checkvs)==0){ ## if this term is not in a variance structure put it inside
rcovtermss[u] <- paste("vsm( ism(",rcovtermss[u],") )")
}
ff <- eval(parse(text = rcovtermss[u]),data,parent.frame()) # evalaute the variance structure
S <- c(S, ff$Z)
Spartitions <- c(Spartitions, ff$partitionsR)
## constraint
residualsNonFixed <- which(ff$thetaC != 3, arr.ind = TRUE)
if(nrow(residualsNonFixed) > 0){
ff$theta[residualsNonFixed] <- ff$theta[residualsNonFixed] * 5
}
theta[[counter]] <- ff$theta
thetaC[[counter]] <- ff$thetaC
thetaF[[counter]] <- ff$thetaF
sp[[counter]] <- ff$sp#rep(ff$sp,length(ff$Z))
baseNames <- which( ff$thetaC > 0, arr.ind = TRUE)
s1 <- paste(rownames(ff$thetaC)[baseNames[,"row"]], colnames(ff$thetaC)[baseNames[,"col"]],sep = ":")
s2 <- paste(all.vars(as.formula(paste("~",rcovtermss[u]))),collapse=":")
rTermsNames[[counter]] <- paste(s2,s1,sep=":")
checkvs <- numeric() # restart the check
counter <- counter + 1
}
#################
#################
## get Xs
data$`1` <-1
newfixed=fixed
fixedTerms <- gsub(" ", "", strsplit(as.character(fixed[3]), split = "[+-]")[[1]])
mf <- try(model.frame(newfixed, data = data, na.action = na.pass), silent = TRUE)
mf <- eval(mf, parent.frame())
X <- Matrix::sparse.model.matrix(newfixed, mf, contrasts.arg=contrasts)
partitionsX <- list()#as.data.frame(matrix(NA,length(fixedTerms),2))
for(ix in 1:length(fixedTerms)){ # save indices for partitions of each fixed effect
effs <- colnames(Matrix::sparse.model.matrix(as.formula(paste("~",fixedTerms[ix],"-1")), mf))
effs2 <- colnames(Matrix::sparse.model.matrix(as.formula(paste("~",fixedTerms[ix])), mf))
partitionsX[[ix]] <- matrix(which(colnames(X) %in% c(effs,effs2)),nrow=1)
}
names(partitionsX) <- fixedTerms
classColumns <- lapply(data,class)
for(ix in 1:length(fixedTerms)){ # clean column names in X matrix
colnamesBase <- colnames(X)[partitionsX[[ix]]]
colnamesBaseList <- strsplit(colnamesBase,":")
toRemoveList <- strsplit(fixedTerms[ix],":")[[1]] # words to remove from the level names in the ix.th fixed effect
# print(toRemoveList)
if("1" %in% unlist(toRemoveList)){}else{toRemoveList <- all.vars(as.formula(paste("~",paste(toRemoveList, collapse = "+"))))}
for(j in 1:length(toRemoveList)){
if( toRemoveList[[j]] %in% names(classColumns) ){
if( classColumns[[toRemoveList[[j]]]] != "numeric"){ # only remove the name from the level if is structure between factors, not for random regressions
nc <- nchar(gsub(" ", "", toRemoveList[[j]], fixed = TRUE)) # number of letters to remove
colnamesBaseList <- lapply(colnamesBaseList, function(h){
if(is.na(h[j])){ # is the intercept? no
return(h)
}else{ # is the intercept? yes
if(length(grep(toRemoveList[[j]],h[j])) == 1){ # if the factor word matches in the level
if(nchar(h[j]) > nc){h[j] <- substr(h[j],1+nc,nchar(h[j]))}
}
return(h)
}
}) # only remove the initial name if the name is actually longer
}
}
}
colnames(X)[partitionsX[[ix]]] <- unlist(lapply(lapply(colnamesBaseList,na.omit), function(x){paste(x, collapse=":")}))
}
step1 <- gsub(" ", "", strsplit(as.character(fixed[3]), split = "[-]")[[1]])
step2 <- unlist(apply(data.frame(step1),1,function(x){strsplit(as.character(x), split = "[+]")[[1]]}))
intercCheck <- ifelse(length(intersect(c("1","-1"),step2)) == 0, TRUE, FALSE) # if length is zero it means that we have an intercept
if(intercCheck){colnames(X)[1] <- "Intercept"}
#################
#################
## weight matrix
if(missing(W)){ # provide W but don't use it
x <- data.frame(d=as.factor(1:length(yvar)))
W <- sparse.model.matrix(~d-1, x)
useH=FALSE
}else{
W <- as(as(as( W , "dMatrix"), "generalMatrix"), "CsparseMatrix") # as(W, Class = "dgCMatrix")
useH=TRUE
}
#################
#################
## information weights
if(is.null(emWeight)){
if(henderson==FALSE){ # p > n
emWeight <- rep(0, nIters)
}else{ # n > p
initialEmSteps <- logspace(round(nIters*.8), 1, 0.009) # 80% of the iterations requested are used for the logarithmic decrease
restEmSteps <- rep(0.009, nIters - length(initialEmSteps)) # the rest we assign a very small emWeight value
emWeight <- c( initialEmSteps, restEmSteps) # plot(emWeight) # we bind both for the modeling
}
}
if(is.null(stepWeight)){
w <- which(emWeight <= .04) # where AI starts
if(length(w) > 1){ # w has at least length = 2
stepWeight <- rep(.9,nIters);
if(nIters > 1){stepWeight[w[1:2]] <- c(0.5,0.7)} # .5, .7
}else{
stepWeight <- rep(.9,nIters);
if(nIters > 1){stepWeight[1:2] <- c(0.5,0.7)} # .5, .7
}
}
#################
#################
## information weights
theta <- lapply(theta, function(x){return(x*Vy)})
thetaFinput <- do.call(adiag1,thetaF)
if(is.null(addScaleParam)){addScaleParam=0}
thetaFinputSP <- unlist(sp)
thetaFinput <- cbind(thetaFinput,thetaFinputSP)
thetaFinput
if(henderson){
nInverses <- length(unlist(lapply(Ai, function(x){attributes(x)$inverse})))
if(nInverses != length(Ai)){
stop("You have selected the 'henderson' algorithm which requires all relationship
matrices to be inverted. Please make sure that you have inverted your
matrices and set the attribute to your matrices as follows:
attr(Gu, 'inverse')=TRUE
where 'Gu' is to be replaced with your matrix name.", call. = FALSE)
}
}
if(returnParam){ # if user just wants to get input matrices
res <- list(yvar=yvar, X=X,Z=Z,Zind=Zind,Ai=Ai,S=S,Spartitions=Spartitions, W=W, useH=useH,
nIters=nIters, tolParConvLL=tolParConvLL, tolParConvNorm=tolParConvNorm,
tolParInv=tolParInv,
verbose=verbose, addScaleParam=addScaleParam,
theta=theta,thetaC=thetaC, thetaFinput=thetaFinput,
stepWeight=stepWeight,emWeight=emWeight,
rtermss=rtermss, partitionsX=partitionsX, getPEV=getPEV
)
}else{
#################################################
if(henderson == FALSE){ # p > n = DIRECT INVERSION: transform all matrices to expected format
# get isInvW
isInvW=FALSE
AI=FALSE # use newton raphson
returnScaled=FALSE # return scaled variance parameters
# translate vsm S into vsm R
R <- rep(list(Matrix::Diagonal(x= rep(0, nrow(yvar)) )), length(S) )
for(iR in 1:length(S)){ # iR=1
R[[iR]][Spartitions[[iR]][1,1]:Spartitions[[iR]][1,2],
Spartitions[[iR]][1,1]:Spartitions[[iR]][1,2] ] = S[[iR]]
}
R <- lapply(R,function(x){as(as(as( x, "dMatrix"), "generalMatrix"), "CsparseMatrix")})
# translate vsm Z into vsm Z
THETA <- THETAc <- K <- Zdi <- list(); counter=1
vary <- var(yvar[,1])
thetaIndex <- thetaConstIndex <- numeric()
for(iTheta in 1:length(theta)){
for(iRow in 1:nrow(theta[[iTheta]])){ # iRow=1
for(iCol in iRow:ncol(theta[[iTheta]])){ # iCol=1
if(theta[[iTheta]][iRow,iCol] != 0){
THETA[[counter]] <- matrix(theta[[iTheta]][iRow,iCol]/vary,1,1)
THETAc[[counter]] <- matrix(thetaC[[iTheta]][iRow,iCol],1,1)
thetaConstIndex[counter] <- thetaC[[iTheta]][iRow,iCol]
thetaIndex[counter] <- iTheta
colnames(THETA[[counter]] ) <- rownames(THETA[[counter]] ) <- colnames(THETAc[[counter]] ) <- rownames(THETAc[[counter]] ) <- paste( colnames(theta[[iTheta]])[iRow], colnames(theta[[iTheta]])[iCol], sep="_" )
# if variance components only (we don't do this for residual vcs)
if(iTheta < length(theta)){
useZs <- which(Zind == iTheta)
if(iRow == iCol){ # if variance component
K[[counter]] <- as.matrix(Ai[[iTheta]])
Zdi[[counter]] <- Z[[useZs[iRow]]]
}else{ # if covariance component
nrowcol <- nrow(Ai[[iTheta]])
Kcov <- matrix(0,nrowcol*2,nrowcol*2)
Kcov[1:nrowcol,(nrowcol+1):nrow(Kcov)] = as.matrix(Ai[[iTheta]])
Kcov[(nrowcol+1):nrow(Kcov),1:nrowcol] = as.matrix(Ai[[iTheta]])
K[[counter]] <- as.matrix(Kcov)
Zdi[[counter]] <- cbind( Z[[useZs[iRow]]], Z[[useZs[iCol]]] )
}
}
# enf of if variance component
counter=counter+1
}
}
}
}
if(!missing(random)){
XZ <- cbind(X,do.call(cbind,Z))
}else{XZ <- X}
# Z <- Zdi; Zdi <- NULL
theta <- THETA; THETA <- NULL
res <- .Call("_sommer_newton_di_sp",PACKAGE = "sommer",
as.matrix(yvar),
list(as.matrix(X)),
list(matrix(1)),
Zdi,K,R,
theta,THETAc,
as.matrix(W),
isInvW,
nIters, tolParConvLL, tolParInv,
AI,getPEV,verbose, returnScaled,
stepWeight, emWeight,
thetaC, thetaIndex)
# res <- newton_di_sp(
# as.matrix(yvar),
# list(as.matrix(X)),
# list(matrix(1)),
# Z,K,R,
# theta,THETAc,
# as.matrix(W),
# isInvW,
# nIters, tolParConvLL, tolParInv,
# AI,getPEV,verbose, returnScaled,
# stepWeight, emWeight,
# thetaC, thetaIndex)
}else if(henderson == TRUE){ # n > p HENDERSON
res <- .Call("_sommer_ai_mme_sp",PACKAGE = "sommer",
X,Z, Zind,
Ai,yvar,
S, Spartitions, W, useH,
nIters, tolParConvLL, tolParConvNorm,
tolParInv,theta,
thetaC,thetaFinput,
addScaleParam,
emWeight,
stepWeight,
verbose)
# res <- ai_mme_sp(
# X,Z, Zind,
# Ai,yvar,
# S, Spartitions, W, useH,
# nIters, tolParConvLL, tolParConvNorm,
# tolParInv,theta,
# thetaC,thetaFinput,
# addScaleParam,
# emWeight,
# stepWeight,
# verbose)
}
###### add rownames and build uList
rownames(res$b) <- colnames(X)
res$thetaC <- thetaC # also residuals
if(!missing(random)){
rownames(res$u) <- unlist(lapply(Z, colnames))
}
rownames(res$bu) <- c(rownames(res$b),rownames(res$u))
rownames(res$monitor) <- unlist(rTermsNames)
res$data <- data
res$y <- yvar
res$partitionsX <- partitionsX
if(!missing(random)){ # mock
names(res$theta) <- names(res$thetaC) <- c(rtermss,"units")
names(res$partitions) <- rtermss
names(res$uList) <- names(res$uPevList) <- rtermss
for(i in 1:length(res$partitions)){ # i=1
colnames(res$uList[[i]]) <- colnames(res$uPevList[[i]]) <- colnames(thetaC[[i]])
rownames(res$uList[[i]]) <- rownames(res$uPevList[[i]]) <- rownames(res$bu)[res$partitions[[i]][1,1]:res$partitions[[i]][1,2]]
}
if(henderson==FALSE){ ######## adding ulist and upevlist similar to henderson mmes
res$W <- XZ
}
} # enf of 'if(missing(random))'
## adding D table for predictions
if(!missing(random)){
res$args <- list(fixed=fixed, random=random, rcov=rcov)
res$Dtable <- data.frame(type=c(rep("fixed",length(res$partitionsX)),
rep("random",length(res$partitions))
),
term=c(names(res$partitionsX),names(res$partitions)),
include=FALSE,average=FALSE)
}else{
res$args <- list(fixed=fixed, rcov=rcov)
res$Dtable <- data.frame(type=c(rep("fixed",length(res$partitionsX))),term=c(names(res$partitionsX),names(res$partitions)),include=FALSE,average=FALSE)
}
#
class(res)<-c("mmes")
}
return(res)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.