-
Notifications
You must be signed in to change notification settings - Fork 0
/
plspmResiduals.R
78 lines (72 loc) · 2.39 KB
/
plspmResiduals.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
##########################################################################################
# plspmResiduals.R
# Description: Function to obtain the residualds from the outer and inner PLS-PM variables
#
# data input:
# -----------
# - pls: An plspm object from the plspm package
#
# @author: Javier Lopatin
#
##########################################################################################
plspmResiduals <- function (pls, Y = NULL) {
if (class(pls) != "plspm")
stop("\n'plspmResiduals()' requires a 'plspm' object")
# checking reflective modes
if (any(pls$model$specs$modes != "A"))
stop("\nSorry, plspmResiduals() only works for mode 'A'")
# checking scaled data
if (!pls$model$specs$scaled)
stop("\nSorry, plspmResiduals() only works with scaled='TRUE'")
# test availibility of dataset (either Y or pls$data)
test_dataset(Y, pls$data, pls$model$gens$obs)
# =======================================================
# inputs setting
# =======================================================
IDM <- pls$model$IDM
blocks <- pls$model$blocks
blocklist = turner::indexify(blocks)
# data matrix DM
if (!is.null(pls$data)) {
DM = pls$data
dataset = TRUE
} else {
dataset = FALSE
# building data matrix 'DM'
DM = get_manifests(Y, blocks)
}
lvs = nrow(IDM)
lvs.names = rownames(IDM)
mvs = pls$model$gen$mvs
# apply the selected scaling
X = get_data_scaled(DM, TRUE)
# =======================================================
# computation of residuals
# =======================================================
Y.lvs <- pls$scores
loads <- pls$outer_model$loading
Path <- pls$path_coefs
endo <- rowSums(IDM)
endo[endo != 0] <- 1
# matrices for storing outer and inner residuals
outer_residuals = DM
inner_residuals = Y.lvs[,endo==1]
# computation of outer residuals
for (j in 1:lvs) {
X.hat = Y.lvs[,j] %*% t(loads[blocklist==j])
# outer residuals
outer_residuals[,blocklist==j] = X[,blocklist==j] - X.hat
}
# computation of inner residuals
# more than 1 endogenous LV
if (sum(endo) != 1)
Y.hat <- Y.lvs %*% t(Path[endo==1,])
# only 1 endogenous LV
if (sum(endo) == 1)
Y.hat = Y.lvs %*% Path[endo==1,]
# inner residuals
inner_residuals = Y.lvs[,endo==1] - Y.hat
out <- list (inner_residuals = inner_residuals, outer_residuals = outer_residuals)
class(out) <- "plspmResiduals"
return (out)
}