https://github.com/cran/HLSM
Tip revision: 281f55f9f8ae3be814d154729507a7fb494e8a92 authored by Tracy Sweet on 06 December 2021, 12:00:02 UTC
version 0.9.0
version 0.9.0
Tip revision: 281f55f
HLSM_run.R
####Function to run the sampler#####
##SPECIFYING PRIORS######
#########################
##if priors = NULL => uses randomly generated priors
##else: priors is a list of following objects:
##MuBeta:= prior mean for betas & intercepts;
##SigmaBeta:= prior variance for betas & intercept;
##MuAlpha:= prior mean for alpha;
##SigmaAlpha:= prior variance for alpha;
##MuZ; VarZ;
##PriorA; PriorB
##TUNING PARAMETERS#######
##########################
##if tune = NULL => uses auto tuning
##else: tune is a list of following objects:
##tuneAlpha = 0.9
##tuneBeta = array, dim=c(PP,KK)
##tuneInt = vec, len = KK
##tuneZ = list( vec(len = nn[x]])) length of list = KK
##############################################################
#library(MASS)
HLSMrandomEF = function(Y,
edgeCov = NULL,
receiverCov = NULL,
senderCov = NULL,
FullX = NULL,
initialVals = NULL,
priors = NULL,
tune = NULL,
tuneIn = TRUE,
dd=2,
niter)
{
#X and Y are provided as list.
if (class(Y) != 'list') {
if (dim(Y)[2] != 4) {
stop('Invalid data structure type')
}
}
# if (class(Y) == 'list' &
# class(Y[[1]]) != 'matrix' &
# class(Y[[1]]) != 'data.frame') {
# stop('Invalid data structure type')
# }
if (class(Y) == 'list') {
KK = length(Y)
if (dim(Y[[1]])[1] == dim(Y[[1]])[2]) {
nn = sapply(1:length(Y), function(x)
nrow(Y[[x]]))
nodenames = lapply(1:length(Y), function(x)
rownames(Y[[x]]))
if(sum(sapply(nodenames, is.null))>=1){nodenames=lapply(1:length(Y), function(x) 1:dim(Y[[x]])[1])}
}
if (dim(Y[[1]])[1] != dim(Y[[1]])[2] & dim(Y[[1]])[2] == 4) {
nn = sapply(1:length(Y), function(x)
length(unique(c(
Y[[x]]$Receiver, Y[[x]]$Sender
))))
nodenames = lapply(1:length(Y), function(x)
unique(c(Y[[x]]$Receiver, Y[[x]]$Sender)))
}
}
if (class(Y) != 'list') {
if (dim(Y)[2] == 4) {
nid = unique(Y$id)
KK = length(nid)
nn = rep(0, KK)
df.list = list()
nodenames = list()
for (k in 1:KK) {
df.sm = Y[which(Y$id == nid[k],),]
nn[k] = length(unique(c(df.sm$Receiver, df.sm$Sender)))
nodenames[[k]] = unique(c(df.sm$Receiver, df.sm$Sender))
df.list[[k]] = array(0, dim = c(nn[k], nn[k]))
dimnames(df.list[[k]])[[1]] = dimnames(df.list[[k]])[[2]] = nodenames[[k]]
for (i in 1:dim(df.sm)[1]) {
df.list[[k]][paste(df.sm$Sender[i]), paste(df.sm$Receiver[i])] = df.sm$Outcome[i] #assume undirected graph and missing items are zeros
}
}
Y = df.list
}
}
##prepare covariates#####
#########################
noCOV = FALSE
if (!is.null(FullX) &
!is.null(edgeCov) &
!is.null(receiverCov) &
!is.null(senderCov))
(stop('FullX cannot be used when nodal or edge covariates are provided'))
if (is.null(FullX) &
is.null(edgeCov) & is.null(receiverCov) & is.null(senderCov)) {
X = lapply(1:KK, function(x)
array(0, dim = c(nn[x], nn[x], 1)))
noCOV = TRUE
}
if (is.null(FullX)) {
if (!is.null(edgeCov) | !is.null(senderCov) | !is.null(receiverCov)) {
if (!is.null(edgeCov)) {
if (class(edgeCov) != 'data.frame') {
stop('edgeCov must be of class data.frame')
}
X1 = getEdgeCov(edgeCov, nn, nodenames)
} else
(X1 = NULL)
if(!is.null(senderCov)){
if(class(senderCov) != 'data.frame'){
stop('senderCov must be of class data.frame')}
X2 = getSenderCov(senderCov, nn,nodenames)
}else(X2 = NULL)
if(!is.null(receiverCov)){
if(class(receiverCov) != 'data.frame'){
stop('receiverCov must be of class data.frame')}
X3 = getReceiverCov(receiverCov, nn,nodenames)
}else(X3 = NULL)
X = lapply(1:KK, function(x){if(!is.null(X1)&!is.null(X2)&!is.null(X3)){
ncov = dim(X1[[x]])[3]+dim(X2[[x]])[3]+dim(X3[[x]])[3];
df = array(0, dim = c(nn[x],nn[x],ncov));
df[,,1:dim(X1[[x]])[3]] = X1[[x]];
df[,,(dim(X1[[x]])[3]+1):(dim(X1[[x]])[3]+dim(X2[[x]])[3])] = X2[[x]];
df[,,(dim(X1[[x]])[3]+dim(X2[[x]])[3]+1):(dim(X1[[x]])[3]+dim(X2[[x]])[3]+dim(X3[[x]])[3])] = X3[[x]] };
if(!is.null(X1)&!is.null(X2) & is.null(X3)){
ncov = dim(X1[[x]])[3]+dim(X2[[x]])[3];
df = array(0, dim = c(nn[x],nn[x],ncov));
df[,,1:dim(X1[[x]])[3]] = X1[[x]];
df[,,(dim(X1[[x]])[3]+1):(dim(X1[[x]])[3]+dim(X2[[x]])[3])] = X2[[x]]};
if(!is.null(X1)&!is.null(X3)&is.null(X2)){
ncov = dim(X1[[x]])[3]+dim(X3[[x]])[3];
df = array(0, dim = c(nn[x],nn[x],ncov));
df[,,1:dim(X1[[x]])[3]] = X1[[x]];
df[,,(dim(X1[[x]])[3]+1):(dim(X1[[x]])[3]+dim(X3[[x]])[3])] = X3[[x]]};
if(!is.null(X2)&!is.null(X3)&is.null(X1)){
ncov = dim(X2[[x]])[3]+dim(X3[[x]])[3];
df = array(0, dim = c(nn[x],nn[x],ncov));
df[,,1:dim(X2[[x]])[3]] = X2[[x]];
df[,,(dim(X2[[x]])[3]+1):(dim(X2[[x]])[3]+dim(X3[[x]])[3])] = X3[[x]]};
if(!is.null(X1)& is.null(X2)& is.null(X3)){
df = X1[[x]] };
if(is.null(X1)& !is.null(X2)& is.null(X3)){
df = X2[[x]] };
if(is.null(X1)& is.null(X2)& !is.null(X3)){
df = X3[[x]] };
return(df) } )
}
}
if (!is.null(FullX))
X = FullX
PP = dim(X[[1]])[3]
XX = unlist(X)
YY = unlist(Y)
YY[which(is.na(YY))] = 0
XX[which(is.na(XX))] = 0
#Priors
if (is.null(priors)) {
MuBeta = rep(0, (PP + 1))
VarBeta = rep(1, (PP + 1))
MuZ = c(0, 0)
VarZ = c(20, 20)
PriorA = 100
PriorB = 150
} else{
if (class(priors) != 'list')
(stop("priors must be of class list, if not NULL"))
MuBeta = priors$MuBeta
VarBeta = priors$VarBeta
MuZ = priors$MuZ
VarZ = priors$VarZ
PriorA = priors$PriorA
PriorB = priors$PriorB
}
##starting values
##Initialization of the latent positions
##first do MDS on the observed network
##then center it
##Procrustean transformation of latent positions
C = lapply(1:KK, function(tt) {
diag(nn[tt]) - (1 / nn[tt]) * array(1, dim = c(nn[tt], nn[tt]))
})
Z0 = lapply(1:KK, function(tt) {
g = graph.adjacency(Y[[tt]])
ss = shortest.paths(g)
ss[ss > 4] = 4
Z0 = cmdscale(ss, k = dd)
dimnames(Z0)[[1]] = dimnames(YY[[tt]])[[1]]
return(Z0)
})
Z00 = lapply(1:KK, function(tt)
C[[tt]] %*% Z0[[tt]])
if (is.null(initialVals)) {
# Z0 = list()
# for(i in 1:KK){
# ZZ = t(replicate(nn[i],rnorm(dd,0,sqrt(10))))
# ZZ[1,]=c(1,0)
# ZZ[2,2]=0
# if(ZZ[2,1] < ZZ[1,1]){
# ZZ[2,1] = -1*(ZZ[2,1]-ZZ[1,1])+1}
# ZZ[3,2] = abs(ZZ[3,2])
# Z0[[i]] = ZZ
# }
Z0 = unlist(Z00)
beta0 = replicate(KK, rnorm(PP, 0, 1))
intercept0 = rnorm(KK, 0, 1)
print("Starting Values Set")
} else{
if (class(initialVals) != 'list')
(stop("initialVals must be of class list, if not NULL"))
Z0 = initialVals$ZZ
beta0 = initialVals$beta
intercept0 = initialVals$intercept
}
###tuning parameters#####
if (is.null(tune)) {
a.number = 5
tuneBeta = array(1, dim = c(PP, KK))
tuneInt = rep(0.2, KK)
tuneZ = lapply(1:KK, function(x)
rep(1.2, nn[x]))
} else{
if (class(tune) != 'list')
(stop("tune must be of class list, if not NULL"))
a.number = 1
tuneBeta = tune$tuneBeta
tuneInt = tune$tuneInt
tuneZ = tune$tuneZ
}
###Tuning the Sampler####
do.again = 1
tuneX = 1
if (tuneIn == TRUE) {
while (do.again == 1) {
print('Tuning the Sampler')
for (counter in 1:a.number) {
rslt = MCMCfunction(
nn = nn,
PP = PP,
KK = KK,
dd = dd,
XX = XX,
YY = YY,
ZZ = Z0,
beta = beta0 ,
intercept = intercept0,
MuBeta = MuBeta,
SigmaBeta = VarBeta,
MuZ = MuZ,
VarZ = VarZ,
tuneBetaAll = tuneBeta,
tuneInt = tuneInt,
tuneZAll = unlist(tuneZ),
niter = 200,
PriorA = PriorA,
PriorB = PriorB
)
tuneZ = lapply(1:KK, function(x)
adjust.my.tune(tuneZ[[x]], rslt$acc$Z[[x]], 2))
tuneBeta = array(sapply(1:KK, function(x)
adjust.my.tune(tuneBeta[, x], rslt$acc$beta[, x], 1)), dim = c(PP, KK))
tuneInt = sapply(1:KK, function(x)
adjust.my.tune(tuneInt[x], rslt$acc$intercept[x], 1))
print(paste('TuneDone = ', tuneX))
tuneX = tuneX + 1
}
extreme = lapply(1:KK, function(x)
which.suck(rslt$acc$Z[[x]], 2))
do.again = max(sapply(extreme, length)) > 5
}
print("Tuning is finished")
}
rslt = MCMCfunction(
nn = nn,
PP = PP,
KK = KK,
dd = dd,
XX = XX,
YY = YY,
ZZ = Z0,
beta = beta0 ,
intercept = intercept0,
MuBeta = MuBeta,
SigmaBeta = VarBeta,
MuZ = MuZ,
VarZ = VarZ,
tuneBetaAll = tuneBeta,
tuneInt = tuneInt,
tuneZAll = unlist(tuneZ),
niter = niter,
PriorA = PriorA,
PriorB = PriorB
)
##Procrutes transformation on the final draws of the latent positions
##
Ztransformed = lapply(1:niter, function(ii) {
lapply(1:KK,
function(tt) {
z = rslt$draws$ZZ[[ii]][[tt]]
z = C[[tt]] %*% z
pr = t(Z00[[tt]]) %*% z
ssZ = svd(pr)
tx = ssZ$v %*% t(ssZ$u)
zfinal = z %*% tx
return(zfinal)
})
})
rslt$draws$ZZ = Ztransformed
rslt$call = match.call()
if (noCOV == TRUE) {
rslt$tune = list(tuneZ = tuneZ, tuneInt = tuneInt)
rslt$draws$Beta = NA
}
if (noCOV == FALSE) {
rslt$tune = list(tuneBeta = tuneBeta,
tuneZ = tuneZ,
tuneInt = tuneInt)
}
class(rslt) = 'HLSM'
rslt
}