This function validates PARAFAC with different numbers of components by means of splitting the data cube in halves, fitting PARAFAC to them and comparing the results [1].
feemsplithalf(
cube, nfac, splits, random, groups, fixed, ..., progress = TRUE
)
# S3 method for feemsplithalf
plot(x, kind = c('tcc', 'factors'), ...)
# S3 method for feemsplithalf
print(x, ...)
# S3 method for feemsplithalf
coef(object, kind = c('tcc', 'factors'), ...)An object of class feemsplithalf, containing named fields:
A list of feemparafac objects containing
the factors of the halves. The list has dimensions, the first one
corresponding to the halves (always 2), the second to different
numbers of factors (as many as in nfac) and the third to
different groupings of the samples (depends on splits or
random).
A named list containing arrays of Tucker's congruence coefficients
between the halves. Each entry in the list corresponds to an element
in the nfac argument. The dimensions of each array in the
list correspond to, in order: the factors (1 to nfac[i]), the
modes (emission or excitation) and the groupings of the samples
(depending on splits or random).
A copy of nfac argument.
A lattice plot object. Its print or plot method
will draw the plot on an appropriate plotting device.
A data.frame containing various columns, depending on
the value of the kind argument:
The factor (out of nfac) under consideration.
Tucker's congruence coefficient between a pair of matching components. Out of two possible values (TCC between excitation loadings or emission loadings), the minimal one is chosen, because the same rule is used to find which components match when reordering them in a pair of models.
The sequence number for each pair of models in the split-half
test, related to the third dimension of object$factors
or object$tcc. May be used to group values for plotting
or aggregation.
Consists of two-element lists containing indices of the samples in each half of the original cube.
The number of factors in the pair of models under consideration.
Emission and excitation wavelengths.
The values of the loadings.
Number of the factor, \(1\) to nfac.
The mode the loading value belongs to, “Emission” or “Excitation”.
Total number of factors.
Sequence number of a split-half test, indicating a given way to split the dataset in a group of splits with the same numbers of factors.
Number of the half, \(1\) or \(2\).
For every row, this is an integer vector indicating the subset of the original data cube that the loadings have been obtained from.
A feemcube object.
An integer vector of numbers of factors to check.
A scalar or a two-element vector consisting of whole numbers.
The first element is the number of parts to split the data cube into, which must be even. After splitting, the parts are recombined into non-intersecting halves [2], which are subjected to PARAFAC decomposition and compared against each other.
The second element, if specified, limits the total number of comparisons between the pairs, since the number of potential ways to recombine the parts of the data cube into halves grows very quickly.
The number of PARAFAC models fitted is
\(
2 \cdot \mathtt{splits[2]}
\). If only splits[1] is
specified, splits[2] defaults to \(
\mathtt{splits[1]} \choose {\mathtt{splits[1]}/2}
\).
Mutually incompatible with the parameters random, fixed.
Number of times to shuffle the dataset, split into non-intersecting halves, fit a PARAFAC model to each of the halves and compare halves against each other.
The number of PARAFAC models fitted is \(2 \cdot \mathtt{random}\).
Mutually incompatible with the parameters splits, fixed.
Use this argument to preserve the ratios between the groups present
in the original dataset when constructing the halves. If specified,
must be a factor or an integer vector of length dim(cube)[3]
(specifying the group each sample belongs to) or a list of them,
i.e., a valid f argument to split. By default,
samples are considered to form a single group.
For the split-combine method (splits), each group must have
at least splits elements; for best results, sizes of groups
should be close to a multiple of splits. For the randomised
split-half method (random), each group should have at least
\(2\) elements.
Mutually incompatible with the fixed parameter.
Use this argument to manually specify the contents of the halves to test. The argument must be a list containing two-element lists specifying the halves to compare. Each half must be a vector consisting of whole numbers specifying sample indices in the cube (see the example).
It is considered an error to specify a sample in both halves.
Mutually incompatible with the parameters splits, random,
groups.
Set to FALSE to disable the progress bar.
An object returned by feemsplithalf.
Chooses what type of data to return or plot:
Statistics of between-half TCCs for different numbers of components. The smallest TCC is chosen between emission- and excitation-mode values, but otherwise they are not aggregated.
When plotting, TCC values for the component with the same number have the same colour.
The resulting loading values.
When plotting, split the plot into panels per each number of components and each mode (emission or excitation). Components with the same number have the same colour.
Remaining options are passed to feemparafac and,
eventually, to parafac. It is recommended to fully
name the parameters instead of relying on partial or positional
matching.
Passed as-is to xyplot.
No additional options are allowed.
As the models (loadings \(\mathbf A\),
\(\mathbf B\) and scores \(\mathbf C\))
are fitted, they are compared to the first model of the same number
of factors (Tucker's congruence coefficient is calculated using
congru for emission and excitation mode factors, then the
smallest value of the two is chosen for the purposes of matching). The
models are first reordered according to the best match by TCC value,
then rescaled [3] by minimising \(
|| \mathbf A \, \mathrm{diag}(\mathbf s_\mathrm A) -
\mathbf A^\mathrm{orig} ||^2
\) and \(
|| \mathbf{B} \, \mathrm{diag}(\mathbf s_\mathrm B) -
\mathbf B^\mathrm{orig} ||^2
\) over \(\mathbf s_\mathrm A\) and
\(\mathbf s_\mathrm B\), subject to \(
\mathrm{diag}(\mathbf s_\mathrm A) \times
\mathrm{diag}(\mathbf s_\mathrm B) \times
\mathrm{diag}(\mathbf s_\mathrm C) = \mathbf I
\), to make them comparable.
To perform stratified sampling on a real-valued variable (e.g. salinity,
depth), consider binning samples into groups using cut,
perhaps after histogram flattening using ecdf(x)(x). To
determine the number of breaks, consider nclass.Sturges.
To conserve memory, feemsplithalf puts the user-provided
cube in an environment and passes it via envir and
subset options of feemparafac. This means that,
unlike in feemparafac, the cube argument has
to be a feemcube object and passing envir and
subset options to feemsplithalf is not supported.
plot.feemsplithalf plots results of the split-half procedure
(TCC or loading values depending on the kind argument)
using lattice graphics. Sane defaults are provided for
xyplot parameters xlab, ylab,
as.table, but they can be overridden.
print.feemsplithalf displays a very short summary of the
analysis, currently the minimum TCC value for each number of components.
coef.feemsplithalf returns the Tucker's congruence
coefficients resulting from the split-half analysis.
tools::toRd(bibentry('Article', author = person(c('Wayne', 'S.'), 'DeSarbo'), title = paste( 'An Application of PARAFAC to a Small Sample Problem,', 'Demonstrating Preprocessing, Orthogonality Constraints,', 'and Split-Half Diagnostic Techniques (Appendix)' ), journal = 'Research Methods for Multimode Data Analysis', year = 1984, pages = '602-642', url = 'https://papers.ssrn.com/abstract=2783446' ))
tools::toRd(bibentry('Article', author = c( person(c('Kathleen', 'R.'), 'Murphy'), person(c('Colin', 'A.'), 'Stedmon'), person('Daniel', 'Graeber'), person('Rasmus', 'Bro') ), title = 'Fluorescence spectroscopy and multi-way techniques. PARAFAC', journal = 'Analytical Methods', doi = '10.1039/c3ay41160e', volume = 5, year = 2013, pages = '6557-6566' ))
tools::toRd(bibentry('Article', author = c( person('Jordi', 'Riu'), person('Rasmus', 'Bro') ), title = paste( 'Jack-knife technique for outlier detection and', 'estimation of standard errors in PARAFAC models' ), journal = 'Chemometrics and Intelligent Laboratory Systems', volume = 65, number = 1, pages = '35-49', year = 2003, doi = '10.1016/S0169-7439(02)00090-4', ))
feemparafac, parafac, congru,
feemcube.
# \donttest{
data(feems)
cube <- feemscale(feemscatter(cube, rep(14, 4)), na.rm = TRUE)
(sh <- feemsplithalf(
cube, 1:4, splits = 4 # => S4C6T3
# splits = c(4, 2) would be S4C4T2, and so on
# the rest is passed to multiway::parafac;
# setting ctol and maxit is recommended
))
# specifying fixed halves to compare as list of 2-element lists
fixed <- list(
list(1:6, 7:12),
list(seq(1, 11, 2), seq(2, 12, 2))
)
sh.f <- feemsplithalf(cube, 2:3, fixed = fixed)
# can use feemparafac methods for individual models in $factors
plot(sh$factors[[1]])
plot(sh)
plot(sh, 'factors')
head(coef(sh))
head(coef(sh, 'factors'))
# }Run the code above in your browser using DataLab