Nothing
################################################################################
# mjca(): Computation of MCA & JCA (ca package 0.70)
################################################################################
# generic mjca()
mjca <- function(obj, ...){
UseMethod("mjca")
}
mjca.table <- function(obj, ...){
obj <- expand.dft(obj)
mjca.default(obj, ...)
}
mjca.array <- function(obj, ...){
if (!all(floor(obj) == obj, na.rm = TRUE)) stop("Input object must contain integers")
obj <- expand.dft(as.table(obj))
mjca.default(obj, ...)
}
mjca.data.frame <- function(obj, ...){
mjca.default(obj, ...)
}
mjca.default <- function(obj,
nd = 2,
lambda = c("adjusted", "indicator", "Burt", "JCA"),
supcol = NA,
subsetcat = NA,
ps = ":",
maxit = 50,
epsilon = 0.0001,
reti = FALSE,
...){
##### Part 1: Input checks:
lambda <- match.arg(lambda)
obj <- data.frame(lapply(data.frame(obj), factor))
subsetcol <- subsetcat
##### Part 2: Data preparation
# Indicator and Burt matrix:
levels.n.0 <- unlist(lapply(obj, nlevels))
rn.0 <- dimnames(obj)[[1]]
cn.0 <- dimnames(obj)[[2]]
n.0 <- cumsum(levels.n.0)
I.0 <- dim(obj)[1]
Q.0 <- dim(obj)[2]
Q.sup <- NA
J.0 <- sum(levels.n.0)
J.sup <- NA
Qind.0 <- 1:Q.0
Qind <- Qind.0
Qind.sup <- NA
ind.0 <- 1:J.0
ind.sub <- NA
ind.sup.foo <- NA
ind.sup <- NA
cn <- dimnames(obj)[[2]]
fn <- rep(names(obj), unlist(lapply(obj, nlevels)))
ln <- unlist(lapply(obj,levels))
col.names <- paste(fn, ln, sep = ps)
# Subsets, supplementary check:
if (!(is.na(subsetcol)[1] & length(subsetcol) == 1)){
# check if given as vector
if (mode(subsetcol) != "list"){
if (sum(subsetcol < 0) == length(subsetcol)){ # check for negative indexes
subsetcol <- (1:sum(levels.n))[subsetcol]
}
lut <- cumsum(levels.n.0) - unlist(levels.n.0)
s0 <- (1:sum(levels.n.0))[subsetcol]
} # end subset-vector
if (mode(subsetcol) == "list"){
s0 <- list()
if (length(subsetcol) < length(obj)){
for (i in (length(subsetcol)+1):length(obj)){
subsetcol[[i]] <- NA
}
}
for (i in 1:length(obj)){
if (is.na(subsetcol[[i]])[1]){
s0[[i]] <- NA
} else {
s0[[i]] <- (1:nlevels(obj[[i]]))[subsetcol[[i]]]
}
}
} # end subset-list
subsetcol <- s0
} # end subset
# Supplementary points:
if (!is.na(supcol)[1]){
Qind <- Qind.0[-supcol]
Qind.sup <- supcol
# get indices for Burt matrix:
for (k in 1:length(supcol)){
ind.sup <- c(ind.sup, (c(0,n.0)[supcol[k]] + 1):(c(0,n.0)[supcol[k]+1]))
}
ind.sup <- ind.sup[-1]
ind <- ind.0[-ind.sup]
Q.sup <- length(supcol)
Q <- Q.0 - Q.sup
J.sup <- sum(levels.n.0[Qind.sup])
J <- sum(levels.n.0[Qind])
# check: subset and supplementary?
ind.sup.foo <- ind.sup
if (!(is.na(subsetcol)[1] & length(subsetcol) == 1)){
ind.sup.foo <- ind.sup.foo - (length(ind) - length(subsetcol))
}
} else {
ind.sup <- NA
ind <- ind.0
Q.sup <- NA
Q <- Q.0
J.sup <- NA
J <- J.0
} # end supplementary
levels.n <- levels.n.0[Qind]
# Subset indexes:
if (!(is.na(subsetcol)[1] & length(subsetcol) == 1)){
ind.sub <- subsetcol
# Levels in Subset:
levels.n.sub <- table(rep(1:Q, levels.n)[subsetcol])
# names(levels.n.sub) <- names(levels.n)
foo <- rep(names(levels.n), levels.n)[subsetcol]
if (is.na(supcol)[1]){
names(levels.n.sub) <- foo[!duplicated(foo)]
} else {
names(levels.n.sub) <- (foo[!duplicated(foo)])[-supcol]
}
Q.sub <- Q - sum(levels.n.sub == 0)
levels.n.sub <- levels.n.sub[levels.n.sub != 0]
}
##### Part 3: 'Core' Computation
### Set up data
# Indicator and Burt matrix:
Z.0 <- matrix(0, nrow = I.0, ncol = J.0)
newdat <- lapply(obj, as.numeric)
offset.b <- c(0, n.0)
offset <- c(0, n.0[-length(n.0)])
for (i in 1:Q.0){
Z.0[1:I.0 + (I.0 * (offset[i] + newdat[[i]] - 1))] <- 1
}
fn <- rep(names(obj), unlist(lapply(obj, nlevels)))
ln <- unlist(lapply(obj,levels))
B.0 <- t(Z.0) %*% Z.0
B <- B.0[ind, ind]
Z <- Z.0[,ind]
P <- B / sum(B)
cm <- apply(P, 2, sum)
rm <- apply(Z.0/sum(Z.0), 1, sum)
S <- diag(sqrt(1/cm)) %*% (P - cm %*% t(cm)) %*% diag(sqrt(1/cm))
evd.S <- eigen(S)
evd.S$values[evd.S$values < 0] <- 0
obj.num <- as.matrix(data.frame(lapply(obj[,Qind], as.numeric)))
rowmass <- rep(1/I.0, I.0) #NA # rep(1/I.0, I.0)
# rowinertia <- apply(((Z.0/sum(Z.0)) - rm %*% t(cm))^2, 1, sum) #NA # apply(S^2, 1, sum)
rowinertia <- apply(((Z/sum(Z)) - rm %*% t(cm))^2, 1, sum) #NA # apply(S^2, 1, sum)
rowdist <- sqrt(rowinertia / rm) #NA # sqrt(rowinertia / rm)
colinertia <- apply(S^2, 2, sum)
coldist <- sqrt(colinertia / cm)
# Burt bits for supplementary variables:
if (!is.na(ind.sup[1])){
B.sup <- B.0[ind.sup, ind]
}
if(!is.na(subsetcol[1])){
if(!is.na(ind.sup[1])){
ind.sub <- c(ind.sup,ind.sub)
ind.sub <- (ind.sub[!duplicated(ind.sub)])[-(1:length(ind.sup))]
subsetcol <- ind.sub
ind.sup.foo <- ind.sup - (length(ind.0)-length(c(ind.sub,ind.sup)))
}
# B.sub <- B[ind.sub,ind.sub]
B.sub <- B.0[ind.sub,ind.sub]
}
# some placeholders for adjusted/JCA
B.star <- NA
lambda.adj <- NA
JCA.it <- list(NA, c(NA, NA))
subin <- subinr(B, levels.n)
# placeholders for rows:
row.ctr <- NA
row.cor <- NA
##### 3.1: 'lambda' = "indicator"
if (lambda == "indicator"){
nd.max <- J - Q
col.sc <- diag(1 / sqrt(cm)) %*% evd.S$vectors[,1:(J-Q)]
col.pc <- col.sc %*% diag(sqrt(evd.S$values[1:(J-Q)]))
# Computations for rows:
if (!is.na(supcol)[1]){
offset.shift <- rep(0, length(Qind))
for (i in 1:length(Qind.sup)){
offset.shift[offset[Qind] > offset[Qind.sup[i]]] <- -offset[Qind.sup[i]]
}
indices <- t(t(obj.num) + offset[Qind] + offset.shift)
row.pc <- matrix(0, nrow = nrow(obj.num), ncol = J-Q)
for(i in 1:nrow(obj.num)){
row.pc[i,] <- apply(col.sc[indices[i,],], 2, sum) / Q
}
} else {
indices <- t(t(obj.num) + offset[Qind])
row.pc <- matrix(0, nrow = nrow(obj.num), ncol = J-Q)
for(i in 1:nrow(obj.num)){
row.pc[i,] <- apply(col.sc[indices[i,],], 2, sum) / Q
}
}
row.sc <- row.pc %*% diag(1/sqrt(evd.S$values[1:(J-Q)]))
col.ctr <- evd.S$vectors[,1:(J-Q)]^2
row.ctr <- (1/nrow(obj.num)) * row.pc^2 %*% diag(1/evd.S$values[1:(J-Q)])
col.cor <- col.pc^2 / apply(col.pc^2, 1, sum)
row.cor <- row.pc^2 / apply(row.pc^2, 1, sum)
lambda0 <- evd.S$values[1:nd.max]
lambda.t <- sum(lambda0)
lambda.e <- lambda0 / lambda.t
lambda.et <- 1
# Subset analysis:
if (!is.na(subsetcol)[1]){
nd.max <- min(length(ind.sub), J-Q)
if (!is.na(supcol)[1]){
subsetcol.shift <- rep(0, length(subsetcol))
subsetcol.ranka <- rank(c(ind.sup,subsetcol))[1:length(ind.sup)]
subsetcol.rankb <- rank(c(ind.sup,subsetcol))[-(1:length(ind.sup))]
for (i in 1:length(ind.sup)){
subsetcol.shift[subsetcol.rankb > subsetcol.ranka[1]] <- subsetcol.shift[subsetcol.rankb > subsetcol.ranka[1]] - 1
}
evd.S <- eigen(S[subsetcol+subsetcol.shift,subsetcol+subsetcol.shift])
} else {
evd.S <- eigen(S[subsetcol,subsetcol])
}
col.sc <- diag(1 / sqrt(cm[subsetcol])) %*% evd.S$vectors[,1:nd.max]
col.pc <- col.sc %*% diag(sqrt(evd.S$values[1:nd.max]))
col.ctr <- evd.S$vectors[,1:nd.max]^2
col.cor <- col.pc^2 / apply(col.pc^2, 1, sum)
lookup <- offset[1:Q]
rpm <- as.matrix(data.frame(newdat))[,1:Q]
indices <- t(t(rpm) + lookup)
row.pc <- matrix(0, nrow = I.0, ncol = nd.max)
for(i in 1:(I.0)) {
profile <- -cm
profile[indices[i,]] <- profile[indices[i,]]+1/Q
profile <- profile[subsetcol]
row.pc[i,] <- t(profile) %*% col.sc
}
row.sc <- row.pc %*% diag(1/sqrt(evd.S$values[1:nd.max]))
row.ctr <- (1/I.0) * row.pc^2 %*% diag(1/evd.S$values[1:nd.max])
row.cor <- row.pc^2 / apply(row.pc^2, 1, sum)
# Subset & Supplementary variables:
if(!is.na(supcol)[1]){
cols.pc <- sweep((B.sup / apply(B.sup, 1, sum))[,subsetcol+subsetcol.shift], 2, cm[subsetcol+subsetcol.shift]) %*% col.sc
cols.sc <- cols.pc %*% diag(1/sqrt(evd.S$values[1:nd.max]))
cols.cor <- cols.pc^2 / apply(cols.pc^2,1,sum)
}
} # END Subset
# Supplementary points:
if (!is.na(supcol)[1] & is.na(subsetcol)[1]){
cols.pc <- (B.sup / apply(B.sup, 1, sum)) %*% col.sc
cols.sc <- cols.pc %*% diag(1 / evd.S$values[1:nd.max])
cols.sqd <- apply((sweep(sweep((B.sup / apply(B.sup,1,sum)), 2, cm), 2, sqrt(cm), FUN = "/"))^2, 1, sum)
cols.cor <- cols.pc^2 / apply(cols.pc^2, 1, sum)
} # End supplementary
} else { # END if "indicator"
##### 3.2: 'lambda' = "Burt"
col.sc <- diag(1/sqrt(cm)) %*% evd.S$vectors[,1:(J-Q)]
col.pc <- col.sc %*% diag(evd.S$values[1:(J-Q)])
### row.sc <- col.sc
### row.pc <- col.pc
#mjca2# row.pc <- t(t(Z) %*% diag(1/apply(Z, 1, sum))) %*% col.sc
row.pc <- (Z/Q) %*% col.sc
row.sc <- row.pc %*% diag(1/evd.S$values[1:(J-Q)])
col.ctr <- evd.S$vectors[,1:(J-Q)]^2
col.cor <- col.pc^2 / apply(col.pc^2, 1, sum)
# Subset analysis:
if (!is.na(subsetcol)[1]){
nd.max <- min(length(ind.sub), J-Q)
# evd.S <- eigen(S[subsetcol,subsetcol])
if (!is.na(supcol)[1]){
subsetcol.shift <- rep(0, length(subsetcol))
subsetcol.ranka <- rank(c(ind.sup,subsetcol))[1:length(ind.sup)]
subsetcol.rankb <- rank(c(ind.sup,subsetcol))[-(1:length(ind.sup))]
for (i in 1:length(ind.sup)){
subsetcol.shift[subsetcol.rankb > subsetcol.ranka[1]] <- subsetcol.shift[subsetcol.rankb > subsetcol.ranka[1]] - 1
}
evd.S <- eigen(S[subsetcol+subsetcol.shift,subsetcol+subsetcol.shift])
} else {
evd.S <- eigen(S[subsetcol,subsetcol])
}
col.sc <- diag(1/sqrt(cm[subsetcol])) %*% evd.S$vectors[,1:nd.max]
col.pc <- col.sc %*% diag(evd.S$values[1:nd.max])
### row.sc <- col.sc
### row.pc <- col.pc
#mjca2# row.pc <- t(t(Z[,subsetcol]) %*% diag(1/apply(Z[,subsetcol], 1, sum))) %*% col.sc
# 0.65: row.pc <- (Z/Q) %*% col.sc
if (!is.na(subsetcol)[1]){
row.pc <- (Z[,subsetcol]/Q) %*% col.sc
} else {
row.pc <- (Z/Q) %*% col.sc
}
## 0.65
row.sc <- row.pc %*% diag(1/evd.S$values[1:nd.max])
col.ctr <- evd.S$vectors[,1:nd.max]^2
col.cor <- col.pc^2 / apply(col.pc^2, 1, sum)
# Subset & Supplementary variables:
if(!is.na(supcol)[1]){
cols.pc <- sweep((B.sup / apply(B.sup, 1, sum))[,subsetcol+subsetcol.shift], 2, cm[subsetcol+subsetcol.shift]) %*% col.sc
# cols.pc <- sweep((B.sup / apply(B.sup, 1, sum))[,subsetcol], 2, cm[subsetcol]) %*% col.sc
cols.sc <- cols.pc %*% diag(1 / evd.S$values[1:nd.max])
cols.cor <- cols.pc^2 / apply(cols.pc^2, 1, sum)
}
} # End Subset
# Supplementary points:
if (!is.na(supcol)[1] & is.na(subsetcol)[1]){
B.sup <- B.0[ind.sup, 1:J]
cols.pc <- (B.sup / apply(B.sup, 1, sum)) %*% col.sc
cols.sc <- cols.pc %*% diag(1/evd.S$values[1:(J-Q)])
cols.cor <- cols.pc^2 / apply(cols.pc^2, 1, sum)
} # End supplementary
nd.max <- J - Q
lambda0 <- (evd.S$values[1:nd.max])^2
# remove NAs in lambda:
lambda0 <- lambda0[!is.na(lambda0)]
nd.max <- min(nd.max, length(lambda0))
lambda.t <- sum(lambda0)
lambda.e <- lambda0 / lambda.t
lambda.et <- 1
##### 3.3: 'lambda' = "adjusted"
if (lambda != "Burt"){
nd.max <- sum(sqrt(lambda0) >= 1/Q, na.rm = TRUE)
B.null <- B - diag(diag(B))
P.null <- B.null / sum(B.null)
S.null <- diag(sqrt(1/cm)) %*% (P.null - cm %*% t(cm)) %*% diag(sqrt(1/cm))
evd.S.null <- eigen(S.null)
K0 <- length(which(evd.S.null$values > 1e-8))
Pe <- P
for(q in 1:Q){
Pe[(offset.b[q]+1):offset.b[q+1],(offset.b[q]+1):offset.b[q+1]] <-
cm[(offset.b[q]+1):offset.b[q+1]] %*% t(cm[(offset.b[q]+1):offset.b[q+1]])
}
Se <- diag(sqrt(1/cm)) %*% (Pe-cm%*%t(cm)) %*% diag(sqrt(1/cm))
inertia.adj <- sum(Se^2) * Q / (Q-1)
col.sc <- diag(1/sqrt(cm)) %*% evd.S.null$vectors[,1:K0]
col.pc <- col.sc %*% diag(evd.S.null$values[1:K0])
### row.sc <- col.sc
### row.pc <- col.pc
#mjca2# row.pc <- t(t(Z) %*% diag(1/apply(Z, 1, sum))) %*% col.sc
row.pc <- (Z/Q) %*% col.sc
row.sc <- row.pc %*% diag(1/evd.S.null$values[1:K0])
col.ctr <- evd.S.null$vectors[,1:K0]^2
col.inr.adj <- apply(Se^2,2,sum) * Q/(Q-1)
col.cor <- diag(cm) %*% col.pc^2 / col.inr.adj
lambda.adj <- ((Q/(Q-1))^2 * (sqrt(lambda0)[1:nd.max] - 1/Q)^2)
lambda.t <- (Q/(Q-1)) * (sum(lambda0) - ((J - Q) / Q^2))
lambda.e <- lambda.adj / lambda.t
lambda.et <- NA
lambda0 <- lambda.adj
# Subset analysis:
if (!is.na(subsetcol)[1]){
if (!is.na(supcol)[1]){
evd.S0 <- eigen(S.null[subsetcol+subsetcol.shift,subsetcol+subsetcol.shift])
} else {
evd.S0 <- eigen(S.null[subsetcol,subsetcol])
}
K0 <- length(which(evd.S0$values>1e-8))
nd.max <- K0
lookup <- offset.b[1:(Q+1)]
Pe <- P
for(q in 1:Q){
Pe[(lookup[q]+1):lookup[q+1],(lookup[q]+1):lookup[q+1]] <-
cm[(lookup[q]+1):lookup[q+1]] %*% t(cm[(lookup[q]+1):lookup[q+1]])
}
Se <- diag(sqrt(1/cm))%*%(Pe-cm%*%t(cm))%*%diag(sqrt(1/cm))
lambda.adj <- evd.S0$values[1:K0]^2
lambda0 <- lambda.adj
if (!is.na(supcol)[1]){
lambda.t <- sum(Se[subsetcol+subsetcol.shift,subsetcol+subsetcol.shift]^2)*Q / (Q-1)
lambda.e <- lambda.adj / lambda.t
col.sc <- diag(1/sqrt(cm[subsetcol+subsetcol.shift])) %*% evd.S0$vectors[,1:K0]
} else {
lambda.t <- sum(Se[subsetcol,subsetcol]^2)*Q / (Q-1)
lambda.e <- lambda.adj / lambda.t
col.sc <- diag(1/sqrt(cm[subsetcol])) %*% evd.S0$vectors[,1:K0]
}
# fix:
if (K0 > 1){
col.pc <- col.sc %*% diag(evd.S0$values[1:K0])
} else{
col.pc <- col.sc %*% matrix(evd.S0$values[1:K0])
}
### row.sc <- col.sc
### row.pc <- col.pc
#mjca2# row.pc <- t(t(Z[,subsetcol]) %*% diag(1/apply(Z[,subsetcol], 1, sum))) %*% col.sc
# 0.65:
if (!is.na(subsetcol)[1]){
row.pc <- (Z[,subsetcol]/Q) %*% col.sc
} else {
row.pc <- (Z/Q) %*% col.sc
}
# row.pc <- (Z/Q) %*% col.sc
## 0.65:
row.sc <- row.pc %*% diag(1/evd.S0$values[1:K0])
# Subset & Supplementary variables:
if(!is.na(supcol)[1]){
col.ctr <- evd.S0$vectors[,1:K0]^2
col.inr.adj.subset <- apply(Se[subsetcol+subsetcol.shift,subsetcol+subsetcol.shift]^2, 2, sum) * Q/(Q-1)
cols.pc <- sweep((B.sup / apply(B.sup, 1, sum))[,subsetcol+subsetcol.shift], 2, cm[subsetcol+subsetcol.shift]) %*% col.sc
cols.sc <- cols.pc %*% diag(1/evd.S0$values[1:K0])
cols.sqd <- apply((sweep(sweep((B.sup/apply(B.sup, 1, sum))[,subsetcol+subsetcol.shift], 2, cm[subsetcol+subsetcol.shift]), 2,
sqrt(cm[subsetcol+subsetcol.shift]), FUN="/"))^2, 1, sum)
cols.cor <- cols.pc^2 / cols.sqd
} else {
col.ctr <- evd.S0$vectors[,1:K0]^2
col.inr.adj.subset <- apply(Se[subsetcol,subsetcol]^2, 2, sum) * Q/(Q-1)
col.cor <- diag(cm[subsetcol]) %*% col.pc^2 / col.inr.adj.subset
}
} # End Subset
# Supplementary points:
if (!is.na(supcol)[1] & is.na(subsetcol)[1]){
B.sup <- B.0[ind.sup, 1:J]
cols.pc <- (B.sup / apply(B.sup, 1, sum)) %*% col.sc
cols.sc <- cols.pc %*% diag(1/evd.S.null$values[1:K0])
cols.cor <- cols.pc^2 / apply(cols.pc^2, 1, sum)
}
##### 3.4: 'lambda' = "JCA"
if (lambda == "JCA"){
if (is.na(nd) | nd > nd.max){
nd <- nd.max
}
B.it <- iterate.mjca(B, lev.n = levels.n, nd = nd, maxit = maxit, epsilon = epsilon)
B.star <- B.it[[1]]
JCA.it <- B.it[[2]]
subin <- subinr(B.star, levels.n)
# 0.65:
# colnames(B.star) <- col.names
# rownames(B.star) <- col.names
##0.65:
P <- B.star / sum(B.star)
cm <- apply(P, 2, sum)
eP <- cm %*% t(cm)
S <- (P - eP) / sqrt(eP)
dec <- eigen(S)
lambda0 <- (dec$values[1:nd.max])^2
col.sc <- as.matrix(dec$vectors[,1:nd.max]) / sqrt(cm)
col.pc <- col.sc %*% diag(sqrt(lambda0))
### row.sc <- col.sc
### row.pc <- col.pc
#mjca2# row.pc <- t(t(Z) %*% diag(1/apply(Z, 1, sum))) %*% col.sc
# 0.65:
# if (!is.na(subsetcol)[1]){
# row.pc <- (Z[,subsetcol]/Q) %*% col.sc
# } else {
row.pc <- (Z/Q) %*% col.sc
# }
# row.pc <- (Z/Q) %*% col.sc
## 0.65:
row.sc <- row.pc %*% diag(1/sqrt(lambda0))
inertia.mod <- sum(subin - diag(diag(subin)))
inertia.discount <- sum(diag(subin))
inertia.expl <- (sum(lambda0[1:nd]) - inertia.discount) / inertia.adj
lambda.e <- rep(NA, nd.max)
lambda.t <- sum(subin)
lambda.et <- (sum(lambda0[1:nd]) - sum(diag(subin))) / (sum(subin)-sum(diag(subin)))
Pm <- B.star / sum(B.star)
Sm <- diag(sqrt(1/cm))%*%(Pm-cm%*%t(cm))%*%diag(sqrt(1/cm))
inertia.col.discount <- rep(0, J)
for(q in 1:Q){
inertia.col.discount[(offset.b[q]+1):(offset.b[q+1])] <-
apply(Sm[(offset.b[q]+1):(offset.b[q+1]), (offset.b[q]+1):(offset.b[q+1])]^2, 2, sum)
}
inertia.col.adj <- apply(Sm^2, 2, sum) - inertia.col.discount
col.ctr <- (apply(cm*col.pc[,1:nd]^2, 1, sum) - inertia.col.discount)/
(sum(lambda0[1:nd])-inertia.discount)
col.cor <- (apply(cm*col.pc[,1:nd]^2, 1, sum) - inertia.col.discount) /
inertia.col.adj
# Subset analysis:
if (!is.na(subsetcol)[1]){
# template matrix:
# foo0 <- rep(1:Q.sub, each = levels.n.sub)
# 0.65:
qstmp.out <- rep(0, length(levels.n.sub))
qstmp <- matrix(1:Q.sub, nrow = 1)
colnames(qstmp) <- cn.0
for (qstmp0 in 1:length(levels.n.sub)){
qstmp.out[qstmp0] <- qstmp[,grep(names(levels.n.sub)[qstmp0], colnames(qstmp))]
}
foo0 <- rep(qstmp.out, levels.n.sub)
## 0.65
# foo0 <- rep(1:Q.sub, levels.n.sub)
foo1 <- (foo0) %*% t(rep(1, sum(levels.n.sub))) - t((foo0) %*%
t(rep(1, sum(levels.n.sub))))
upd.template <- ifelse(foo1 == 0, TRUE, FALSE)
cat.template <- rep(FALSE, J)
if (!is.na(supcol)[1]){
cat.template[subsetcol + subsetcol.shift] <- TRUE
} else {
cat.template[subsetcol] <- TRUE
}
Bsub.margin <- apply(B.star, 1, sum) / sum(B.star)
Bsub.red.margin <- Bsub.margin[cat.template]
Bsub.red <- B.star[cat.template,cat.template]
Bsub.red.P <- Bsub.red / sum(B.star)
Bsub.red.S <- diag(1/sqrt(Bsub.red.margin)) %*% (Bsub.red.P -
Bsub.red.margin %*% t(Bsub.red.margin)) %*% diag(1/sqrt(Bsub.red.margin))
Bsub.red.SVD <- svd(Bsub.red.S)
Bsub.red.est <- Bsub.red.margin %*% t(Bsub.red.margin) + diag(sqrt(Bsub.red.margin)) %*%
(Bsub.red.SVD$u[,1:nd] %*% diag(Bsub.red.SVD$d[1:nd]) %*%
t(Bsub.red.SVD$v[,1:nd])) %*% diag(sqrt(Bsub.red.margin))
Bsub.red.P.mod <- (1-upd.template) * Bsub.red.P + upd.template * Bsub.red.est
Bsub.red.S <- diag(1/sqrt(Bsub.red.margin)) %*% (Bsub.red.P.mod - Bsub.red.margin %*%
t(Bsub.red.margin)) %*% diag(1/sqrt(Bsub.red.margin))
Bsub.red.SVD <- svd(Bsub.red.S)
# iterations:
it <- TRUE
k <- 0
while (it){
Bsub.red.P.previous <- Bsub.red.P.mod
Bsub.red.est <- Bsub.red.margin %*% t(Bsub.red.margin) +
diag(sqrt(Bsub.red.margin)) %*% (Bsub.red.SVD$u[,1:nd] %*%
diag(Bsub.red.SVD$d[1:nd]) %*% t(Bsub.red.SVD$v[,1:nd])) %*%
diag(sqrt(Bsub.red.margin))
Bsub.red.P.mod <- (1 - upd.template) * Bsub.red.P + upd.template * Bsub.red.est
Bsub.red.S <- diag(1/sqrt(Bsub.red.margin)) %*% (Bsub.red.P.mod - Bsub.red.margin %*%
t(Bsub.red.margin)) %*% diag(1/sqrt(Bsub.red.margin))
Bsub.red.SVD <- svd(Bsub.red.S)
if (max(abs(Bsub.red.P.mod - Bsub.red.P.previous)) < epsilon | k >= maxit){
it <- FALSE
}
k <- k + 1
}
inertia.adj.red.discount <- sum((upd.template * Bsub.red.S)^2)
inertia.adj.red.subset <- sum(Bsub.red.S^2) - inertia.adj.red.discount
col.sc <- sqrt(1/cm[cat.template]) * Bsub.red.SVD$v[,1:nd]
col.pc <- col.sc %*% diag(Bsub.red.SVD$d[1:nd])
### row.sc <- col.sc
### row.pc <- col.pc
#mjca2# row.pc <- t(t(Z[,subsetcol]) %*% diag(1/apply(Z[,subsetcol], 1, sum))) %*% col.sc
# 0.65:
# row.pc <- (Z/Q) %*% col.sc
if (!is.na(subsetcol)[1]){
row.pc <- (Z[,subsetcol]/Q) %*% col.sc
} else {
row.pc <- (Z/Q) %*% col.sc
}
## 0.65:
row.sc <- row.pc %*% diag(1/Bsub.red.SVD$d[1:nd])
Sm <- Bsub.red.S
inertia.col.red.discount <- apply((upd.template * Sm)^2, 2, sum )
inertia.col.red.adj <- apply(Sm^2, 2, sum) - inertia.col.red.discount
col.ctr <- (apply(cm[cat.template]*col.pc[,1:nd]^2, 1, sum) - inertia.col.red.discount) /
(sum(Bsub.red.SVD$d[1:nd]^2) - inertia.adj.red.discount)
col.cor <- (apply(cm[cat.template]*col.pc[,1:nd]^2, 1, sum) - inertia.col.red.discount) / inertia.col.red.adj
# Subset & Supplementary variables:
if(!is.na(supcol)[1]){
cols.pc <- sweep((B.sup / apply(B.sup, 1, sum))[,cat.template], 2, cm[cat.template]) %*% col.sc
cols.sc <- cols.pc %*% diag(1 / Bsub.red.SVD$d[1:nd])
cols.sqd <- apply((sweep(sweep((B.sup / apply(B.sup, 1, sum))[,cat.template], 2,
cm[cat.template]), 2, sqrt(cm[cat.template]), FUN = "/"))^2, 1, sum)
cols.cor <- apply(cols.pc[,1:nd]^2, 1, sum) / cols.sqd
}
} # End Subset
# Supplementary points:
if (!is.na(supcol)[1] & is.na(subsetcol)[1]){
B.sup <- B.0[ind.sup, 1:J]
cols.pc <- (B.sup / apply(B.sup, 1, sum)) %*% col.sc
cols.sc <- cols.pc %*% diag(1 / lambda0)
cols.sqd <- apply((sweep(sweep((B.sup/apply(B.sup,1,sum)), 2, cm), 2, sqrt(cm), FUN="/"))^2, 1, sum)
cols.cor <- apply(cols.pc[,1:nd]^2, 1, sum) / cols.sqd
}
} # END if "JCA"
} # END if !"Burt"
} # END else if "indicator"
if (!is.na(supcol)[1]){
# colcoord <- rbind(col.sc, cols.sc)
# colpcoord <- rbind(col.pc, cols.pc)
colcoord <- rbind(col.sc, cols.sc)
colcoord[ind.sup,] <- cols.sc
colcoord[-ind.sup,] <- col.sc
colpcoord <- rbind(col.pc, cols.pc)
colpcoord[ind.sup,] <- cols.pc
colpcoord[-ind.sup,] <- col.pc
if (lambda != "JCA"){
colctr <- rbind(col.ctr, matrix(NA, nrow = length(ind.sup), ncol = ncol(col.ctr)))
colctr[ind.sup,] <- matrix(NA, nrow = length(ind.sup), ncol = ncol(col.ctr))
colctr[-ind.sup,] <- col.ctr
col.ctr <- colctr
colcor <- rbind(col.cor, cols.cor)
colcor[ind.sup,] <- cols.cor
colcor[-ind.sup,] <- col.cor
} else {
colctr <- c(col.ctr, rep(NA, length(ind.sup)))
colctr[ind.sup] <- rep(NA, length(ind.sup))
colctr[-ind.sup] <- col.ctr
col.ctr <- colctr
colcor <- c(col.cor, cols.cor)
colcor[ind.sup] <- cols.cor
colcor[-ind.sup] <- col.cor
}
} else {
colcoord <- col.sc
colpcoord <- col.pc
colcor <- col.cor
}
col.names0 <- col.names
if (!is.na(subsetcol[1])){
cm <- cm[ind.sub]
coldist <- coldist[ind.sub]
colinertia <- colinertia[ind.sub]
col.names0 <- col.names[ind.sub]
if(!is.na(supcol)[1]){
col.names0 <- c(col.names0,col.names[ind.sup])
}
B.out <- B.sub
} else {
B.out <- B.0
}
colctr <- col.ctr
rowcoord <- row.sc
rowpcoord <- row.pc
if(!is.na(supcol)[1]){
# colinertia <- c(colinertia, rep(NA, J.sup))
# coldist <- c(coldist, rep(NA, J.sup))
# cm <- c(cm, rep(NA, J.sup))
colinertia0 <- rep(0, length(ind.0))
colinertia0[ind] <- colinertia
colinertia0[ind.sup] <- NA
colinertia <- colinertia0
coldist0 <- rep(0, length(ind.0))
coldist0[ind] <- coldist
coldist0[ind.sup] <- NA
coldist <- coldist0
cm0 <- rep(0, length(ind.0))
cm0[ind] <- cm
cm0[ind.sup] <- NA
cm <- cm0
}
col.names <- col.names0
# (2014-10, returning Indicator matrix)
if (reti == TRUE){
indmat <- Z.0
# 0.65:
colnames(indmat) <- col.names
rownames(indmat) <- rn.0
##0.65:
} else {
indmat <- NA
}
# balkan solution for colcor > 1 (2011-09):
# adjusted analysis only!
if (lambda == "adjusted"){
foo0 <- apply(colcor, 1, max) > 1
if (sum(foo0) > 0){
insert <- c(1, rep(0, dim(colcor)[2]-1))
colcor[foo0,] <- matrix(insert, nrow = sum(foo0), ncol = dim(colcor)[2], byrow = TRUE)
}
}
factors <- cbind(factor = fn, level = ln)
# add row- and columnnames to Burt matrix
if (!is.na(subsetcol[1]) & !is.na(ind.sup.foo[1]) ){
dimnames(B.out) <- list(col.names[-ind.sup.foo], col.names[-ind.sup.foo])
} else {
dimnames(B.out) <- list(col.names, col.names)
}
### 0.70 fix
# colnames(subin) <- cn.0
# rownames(subin) <- cn.0
if (is.na(supcol[1])){
colnames(subin) <- cn.0
rownames(subin) <- cn.0
} else {
colnames(subin) <- cn.0[-supcol]
rownames(subin) <- cn.0[-supcol]
}
# wrap up results
mjca.output <- list(sv = sqrt(lambda0),
lambda = lambda,
inertia.e = lambda.e,
inertia.t = lambda.t,
inertia.et = lambda.et,
levelnames = col.names,
factors = factors,
levels.n = levels.n.0,
nd = nd,
nd.max = nd.max,
rownames = rn.0,
rowmass = rowmass,
rowdist = rowdist,
rowinertia = rowinertia,
rowcoord = rowcoord,
rowpcoord = rowpcoord,
rowctr = row.ctr,
rowcor = row.cor,
colnames = cn.0,
colmass = cm,
coldist = coldist,
colinertia = colinertia,
colcoord = colcoord,
colpcoord = colpcoord,
colctr = col.ctr,
colcor = colcor,
colsup = ind.sup.foo,
subsetcol = subsetcol,
Burt = B.out,
Burt.upd = B.star,
subinertia = subin,
JCA.iter = JCA.it,
indmat = indmat,
call = match.call())
class(mjca.output) <- "mjca"
return(mjca.output)
}
################################################################################
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.