The package rofanova implements the robust nonparametric functional ANOVA method (RoFANOVA) proposed by Centofanti et al. (2021). RoFANOVA addresses the functional analysis of variance (FANOVA) problem, which aims to identify the presence of significant differences, in terms of functional mean, among groups of a functional data, by being robust against the presence of possible outliers. It is a permutation test whose test statistics rely on the functional equivariant M-estimator, the functional extension of the classical robust M-estimator, which is based on the functional normalized median absolute deviation (FuNMAD) estimator.
The main function is rofanova
which implements the
RoFANOVA method both for univariate and bi-variate functional data by
using several families of loss functions. The functions
fusem
and funmad
implement the functional
equivariant M-estimator and the FuNMAD estimator, respectively.
You can install the development version of rofanova from GitHub with:
# install.packages("devtools")
::install_github("unina-sfere/rofanova") devtools
This is a basic example which shows you how to apply the main
function rofanova
to perform both one-way and two-way
FANOVA when data are univariate functional data. The data are generated
as described in the first scenario of the simulation study in Centofanti
et al. (2021).
We start by loading and attaching the rofanova package.
library(rofanova)
Then, we generate the data and, just as an example, we fix the number of permutations B to 20.
<-simulate_data(scenario="one-way")
data_out=data_out$label_1
label_1<-data_out$X_fdata
X_fdata=20 B
We compute the p-values corresponding to the RoFANOVA test with the median, the Huber, the bisquare, the Hampel, and the optimal loss functions.
<-rofanova(X_fdata,label_1,B = B,family="median")
per_list_median<-per_list_median$pval_vec
pvalue_median<-rofanova(X_fdata,label_1,B = B,family="huber")
per_list_huber<-per_list_huber$pval_vec
pvalue_huber<-rofanova(X_fdata,label_1,B = B,family="bisquare")
per_list_bisquare<-per_list_bisquare$pval_vec
pvalue_bisquare<-rofanova(X_fdata,label_1,B = B,family="hampel")
per_list_hampel<-per_list_hampel$pval_vec
pvalue_hampel<-rofanova(X_fdata,label_1,B = B,family="optimal")
per_list_optimal<-per_list_optimal$pval
pvalue_optimal<-c(pvalue_median,pvalue_huber,pvalue_bisquare,pvalue_hampel,pvalue_optimal)
pvaluesnames(pvalues)=c("median", "Huber", "bisquare", "Hampel", "optimal")
The p-values for the significance of the main factor are
print(pvalues)
#> median Huber bisquare Hampel optimal
#> 0.70 0.80 0.65 0.65 0.70
Similarly, two-way FANOVA can be performed as follows.
<-simulate_data(scenario="two-way")
data_out=data_out$label_1
label_1=data_out$label_2
label_2<-data_out$X_fdata
X_fdata=20
B<-rofanova(X_fdata,label_1,label_2,B = B,family="median")
per_list_median<-per_list_median$pval_vec
pvalue_median<-rofanova(X_fdata,label_1,label_2,B = B,family="huber")
per_list_huber<-per_list_huber$pval_vec
pvalue_huber<-rofanova(X_fdata,label_1,label_2,B = B,family="bisquare")
per_list_bisquare<-per_list_bisquare$pval_vec
pvalue_bisquare<-rofanova(X_fdata,label_1,label_2,B = B,family="hampel")
per_list_hampel<-per_list_hampel$pval_vec
pvalue_hampel<-rofanova(X_fdata,label_1,label_2,B = B,family="optimal")
per_list_optimal<-per_list_optimal$pval
pvalue_optimal<-cbind(pvalue_median,pvalue_huber,pvalue_bisquare,pvalue_hampel,pvalue_optimal)
pvaluescolnames(pvalues)=c("median", "Huber", "bisquare", "Hampel", "optimal")
The p-values for the significance of the whole model, the two main factors and the interaction are
print(pvalues)
#> median Huber bisquare Hampel optimal
#> MOD 0.45 0.40 0.45 0.40 0.15
#> F1 0.65 0.55 0.75 0.55 0.50
#> F2 0.40 0.80 0.70 0.65 0.40
#> INT 0.40 0.30 0.15 0.30 0.15