The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Introduction to FSHybridPLS

Overview

FSHybridPLS fits Hybrid Penalized Partial Least Squares models when predictors include both functional curves and scalar covariates. Functional and scalar parts are treated jointly in a hybrid Hilbert space, with roughness penalties on functional coefficient directions.

The method is described in Mun and Jang (2026), doi:10.48550/arXiv.2601.16364.

Construct hybrid predictors

A predictor_hybrid object stores scalar covariates, functional fd objects, and precomputed Gram / penalty matrices used by the algorithm.

library(FSHybridPLS)
set.seed(1)

sim <- simulate_hybrid_data(
  n = 50,
  n_functional = 1,
  n_scalar = 3,
  n_basis = 6
)

sim$W
#> $Z
#>                 Z1           Z2          Z3
#>  [1,]  0.893673702  1.473881181  1.07444096
#>  [2,] -1.047298149  0.677268492  1.89565477
#>  [3,]  1.971337386  0.379962687 -0.60299730
#>  [4,] -0.383632106 -0.192798426 -0.39086782
#>  [5,]  1.654145302  1.577891795 -0.41622203
#>  [6,]  1.512212694  0.596234109 -0.37565742
#>  [7,]  0.082965734 -1.173576941 -0.36663095
#>  [8,]  0.567220915 -0.155642535 -0.29567745
#>  [9,] -1.024548480 -1.918909820  1.44182041
#> [10,]  0.323006503 -0.195258846 -0.69753829
#> [11,]  1.043612458 -2.592327670 -0.38816751
#> [12,]  0.099078487  1.314002167  0.65253645
#> [13,] -0.454136909 -0.635543001  1.12477245
#> [14,] -0.655781852 -0.429978839 -0.77211080
#> [15,] -0.035922423 -0.169318332 -0.50808622
#> [16,]  1.069161461  0.612218174  0.52362059
#> [17,] -0.483974930  0.678340177  1.01775423
#> [18,] -0.121010111  0.567951972 -0.25116459
#> [19,] -1.294140004 -0.572542604 -1.42999345
#> [20,]  0.494312836 -1.363291256  1.70912103
#> [21,]  1.307901520 -0.388722244  1.43506957
#> [22,]  1.497041009  0.277914132 -0.71037115
#> [23,]  0.814702731 -0.823081122 -0.06506757
#> [24,] -1.869788790 -0.068840934 -1.75946874
#> [25,]  0.482029504 -1.167662326  0.56972297
#> [26,]  0.456135603 -0.008309014  1.61234680
#> [27,] -0.353400286  0.128855402 -1.63728065
#> [28,]  0.170489471 -0.145875628 -0.77956851
#> [29,] -0.864035954 -0.163910957 -0.64117693
#> [30,]  0.679230774  1.763552003 -0.68113139
#> [31,] -0.327101015  0.762586512 -2.03328560
#> [32,] -1.569082185  1.111431081  0.50096356
#> [33,] -0.367450756 -0.923206953 -1.53179814
#> [34,]  1.364434929  0.164341838 -0.02499764
#> [35,] -0.334281365  1.154825187  0.59298472
#> [36,]  0.732750042 -0.056521425 -0.19819542
#> [37,]  0.946585640 -2.129360648  0.89200839
#> [38,]  0.004398704  0.344845762 -0.02571507
#> [39,] -0.352322306 -1.904955446 -0.64766045
#> [40,] -0.529695509 -0.811170153  0.64635942
#> [41,]  0.739589226  1.324004321 -0.43383274
#> [42,] -1.063457415  0.615636849  1.77261118
#> [43,]  0.246210844  1.091668956 -0.01825971
#> [44,] -0.289499367  0.306604862  0.85281499
#> [45,] -2.264889356 -0.110158762  0.20516290
#> [46,] -1.408850456 -0.924312773 -3.00804860
#> [47,]  0.916019329  1.592913754 -1.36611193
#> [48,] -0.191278951  0.045010598 -0.42410226
#> [49,]  0.803283216 -0.715128401  0.23680366
#> [50,]  1.887474463  0.865223100 -2.34272312
#> 
#> $functional_list
#> $functional_list[[1]]
#> $coefs
#>          reps 1     reps 2      reps 3      reps 4      reps 5      reps 6
#> [1,] -0.6264538  0.4874291 -0.62124058  0.82122120  0.61982575  1.35867955
#> [2,]  0.1836433  0.7383247 -2.21469989  0.59390132 -0.05612874 -0.10278773
#> [3,] -0.8356286  0.5757814  1.12493092  0.91897737 -0.15579551  0.38767161
#> [4,]  1.5952808 -0.3053884 -0.04493361  0.78213630 -1.47075238 -0.05380504
#> [5,]  0.3295078  1.5117812 -0.01619026  0.07456498 -0.47815006 -1.37705956
#> [6,] -0.8204684  0.3898432  0.94383621 -1.98935170  0.41794156 -0.41499456
#>          reps 7     reps 8     reps 9    reps 10     reps 11    reps 12
#> [1,] -0.3942900  0.6969634 -0.1123462  1.4330237  2.40161776 -1.8049586
#> [2,] -0.0593134  0.5566632  0.8811077  1.9803999 -0.03924000  1.4655549
#> [3,]  1.1000254 -0.6887557  0.3981059 -0.3672215  0.68973936  0.1532533
#> [4,]  0.7631757 -0.7074952 -0.6120264 -1.0441346  0.02800216  2.1726117
#> [5,] -0.1645236  0.3645820  0.3411197  0.5697196 -0.74327321  0.4755095
#> [6,] -0.2533617  0.7685329 -1.1293631 -0.1350546  0.18879230 -0.7099464
#>           reps 13     reps 14    reps 15    reps 16     reps 17    reps 18
#> [1,]  0.610726353  0.07434132  0.5939462 -0.5425200 -1.27659221 -0.9109216
#> [2,] -0.934097632 -0.58952095  0.3329504  1.2078678 -0.57326541  0.1580288
#> [3,] -1.253633400 -0.56866873  1.0630998  1.1604026 -1.22461261 -0.6545846
#> [4,]  0.291446236 -0.13517862 -0.3041839  0.7002136 -0.47340064  1.7672873
#> [5,] -0.443291873  1.17808700  0.3700188  1.5868335 -0.62036668  0.7167075
#> [6,]  0.001105352 -1.52356680  0.2670988  0.5584864  0.04211587  0.9101742
#>         reps 19    reps 20    reps 21     reps 22    reps 23     reps 24
#> [1,]  0.3841854 -0.2073807 -0.5059575 -0.07356440  0.5314962 -0.65209478
#> [2,]  1.6821761 -0.3928079  1.3430388 -0.03763417 -1.5183941 -0.05689678
#> [3,] -0.6357365 -0.3199929 -0.2145794 -0.68166048  0.3065579 -1.91435943
#> [4,] -0.4616447 -0.2791133 -0.1795565 -0.32427027 -1.5364498  1.17658331
#> [5,]  1.4322822  0.4941883 -0.1001907  0.06016044 -0.3009761 -1.66497244
#> [6,] -0.6506964 -0.1773305  0.7126663 -0.58889449 -0.5282799 -0.46353040
#>          reps 25     reps 26    reps 27    reps 28     reps 29     reps 30
#> [1,] -1.11592011  0.45018710  1.0000288  1.0584830 -0.14439960 -0.33400084
#> [2,] -0.75081900 -0.01855983 -0.6212667  0.8864227  0.20753834 -0.03472603
#> [3,]  2.08716655 -0.31806837 -1.3844268 -0.6192430  2.30797840  0.78763961
#> [4,]  0.01739562 -0.92936215  1.8692906  2.2061025  0.10580237  2.07524501
#> [5,] -1.28630053 -1.48746031  0.4251004 -0.2550270  0.45699881  1.02739244
#> [6,] -1.64060553 -1.07519230 -0.2386471 -1.4244947 -0.07715294  1.20790840
#>         reps 31    reps 32    reps 33    reps 34     reps 35    reps 36
#> [1,] -1.2313234  1.4645873 -0.7317482  0.4119747 -2.28523554 -0.1643758
#> [2,]  0.9838956 -0.7660820  0.8303732 -0.3810761  2.49766159  0.4206946
#> [3,]  0.2199248 -0.4302118 -1.2080828  0.4094018  0.66706617 -0.4002467
#> [4,] -1.4672500 -0.9261095 -1.0479844  1.6888733  0.54132734 -1.3702079
#> [5,]  0.5210227 -0.1771040  1.4411577  1.5865884 -0.01339952  0.9878383
#> [6,] -0.1587546  0.4020118 -1.0158475 -0.3309078  0.51010842  1.5197450
#>          reps 37    reps 38    reps 39      reps 40    reps 41    reps 42
#> [1,] -0.30874057 -0.6303003  0.1971934 -0.059723276  0.7073107 -0.5447907
#> [2,] -1.25328976 -0.3409686  0.2631756 -0.098178744  1.0341077 -0.2556707
#> [3,]  0.64224131 -1.1565724 -0.9858267  0.560820729  0.2234804 -0.1661210
#> [4,] -0.04470914  1.8031419 -2.8889207 -1.186458639 -0.8787076  1.0204639
#> [5,] -1.73321841 -0.3311320 -0.6404817  1.096777044  1.1629646  0.1362219
#> [6,]  0.00213186 -1.6055134  0.5705076 -0.005344028 -2.0001649  0.4071676
#>          reps 43    reps 44    reps 45    reps 46    reps 47    reps 48
#> [1,] -0.06965481  0.3747244  1.7196273 -0.2589326 -2.2891240  1.3242586
#> [2,] -0.24766434 -0.4252677  0.2700549  0.3943792  0.7410012 -0.7012317
#> [3,]  0.69555081  0.9510128 -0.4221840 -0.8518571 -1.3162452 -0.5806143
#> [4,]  1.14622836 -0.3892372 -1.1891133  2.6491669  0.9198037 -1.0010722
#> [5,] -2.40309621 -0.2843307 -0.3310330  0.1560117  0.3981302 -0.6681786
#> [6,]  0.57273956  0.8574098 -0.9398293  1.1302073 -0.4075286  0.9451850
#>         reps 49    reps 50
#> [1,]  0.4337021  1.7784293
#> [2,]  1.0051592  0.1344477
#> [3,] -0.3901187  0.7655990
#> [4,]  0.3763703  0.9551367
#> [5,]  0.2441649 -0.0505657
#> [6,] -1.4262573 -0.3058154
#> 
#> $basis
#> $call
#> basisfd(type = type, rangeval = rangeval, nbasis = nbasis, params = params, 
#>     dropind = dropind, quadvals = quadvals, values = values, 
#>     basisvalues = basisvalues)
#> 
#> $type
#> [1] "bspline"
#> 
#> $rangeval
#> [1] 0 1
#> 
#> $nbasis
#> [1] 6
#> 
#> $params
#> [1] 0.3333333 0.6666667
#> 
#> $dropind
#> NULL
#> 
#> $quadvals
#> NULL
#> 
#> $values
#> list()
#> 
#> $basisvalues
#> list()
#> 
#> $names
#> [1] "bspl4.1" "bspl4.2" "bspl4.3" "bspl4.4" "bspl4.5" "bspl4.6"
#> 
#> attr(,"class")
#> [1] "basisfd"
#> 
#> $fdnames
#> $fdnames$args
#> [1] "time"
#> 
#> $fdnames$reps
#>  [1] "reps 1"  "reps 2"  "reps 3"  "reps 4"  "reps 5"  "reps 6"  "reps 7" 
#>  [8] "reps 8"  "reps 9"  "reps 10" "reps 11" "reps 12" "reps 13" "reps 14"
#> [15] "reps 15" "reps 16" "reps 17" "reps 18" "reps 19" "reps 20" "reps 21"
#> [22] "reps 22" "reps 23" "reps 24" "reps 25" "reps 26" "reps 27" "reps 28"
#> [29] "reps 29" "reps 30" "reps 31" "reps 32" "reps 33" "reps 34" "reps 35"
#> [36] "reps 36" "reps 37" "reps 38" "reps 39" "reps 40" "reps 41" "reps 42"
#> [43] "reps 43" "reps 44" "reps 45" "reps 46" "reps 47" "reps 48" "reps 49"
#> [50] "reps 50"
#> 
#> $fdnames$funs
#> [1] "values"
#> 
#> 
#> attr(,"class")
#> [1] "fd"
#> 
#> 
#> $gram_list
#> $gram_list[[1]]
#>              [,1]         [,2]         [,3]         [,4]         [,5]
#> [1,] 0.0476190476 0.0291666667 0.0061507937 0.0003968254 0.0000000000
#> [2,] 0.0291666667 0.0738095238 0.0520833333 0.0114583333 0.0001488095
#> [3,] 0.0061507937 0.0520833333 0.1089285714 0.0709821429 0.0114583333
#> [4,] 0.0003968254 0.0114583333 0.0709821429 0.1089285714 0.0520833333
#> [5,] 0.0000000000 0.0001488095 0.0114583333 0.0520833333 0.0738095238
#> [6,] 0.0000000000 0.0000000000 0.0003968254 0.0061507937 0.0291666667
#>              [,6]
#> [1,] 0.0000000000
#> [2,] 0.0000000000
#> [3,] 0.0003968254
#> [4,] 0.0061507937
#> [5,] 0.0291666667
#> [6,] 0.0476190476
#> 
#> 
#> $gram_deriv_list
#> $gram_deriv_list[[1]]
#>        [,1]     [,2]     [,3]     [,4]     [,5]   [,6]
#> [1,]  324.0 -445.500   94.500   27.000    0.000    0.0
#> [2,] -445.5  648.000 -182.250  -30.375   10.125    0.0
#> [3,]   94.5 -182.250  121.500  -30.375  -30.375   27.0
#> [4,]   27.0  -30.375  -30.375  121.500 -182.250   94.5
#> [5,]    0.0   10.125  -30.375 -182.250  648.000 -445.5
#> [6,]    0.0    0.000   27.000   94.500 -445.500  324.0
#> 
#> 
#> $eval_point
#>  [1] 0.00 0.02 0.04 0.06 0.08 0.10 0.12 0.14 0.16 0.18 0.20 0.22 0.24 0.26 0.28
#> [16] 0.30 0.32 0.34 0.36 0.38 0.40 0.42 0.44 0.46 0.48 0.50 0.52 0.54 0.56 0.58
#> [31] 0.60 0.62 0.64 0.66 0.68 0.70 0.72 0.74 0.76 0.78 0.80 0.82 0.84 0.86 0.88
#> [46] 0.90 0.92 0.94 0.96 0.98 1.00
#> 
#> $n_basis_list
#> [1] 6
#> 
#> $n_sample
#> [1] 50
#> 
#> $n_functional
#> [1] 1
#> 
#> $n_scalar
#> [1] 3
#> 
#> attr(,"class")
#> [1] "predictor_hybrid"
length(sim$y)
#> [1] 50

Split and normalize

split_and_normalize_all() performs a train/test split, within-modality standardization, between-modality variance balancing, and response standardization using training statistics.

prep <- split_and_normalize_all(sim$W, sim$y, train_ratio = 0.7)
prep$predictor_train$n_sample
#> [1] 35
prep$predictor_test$n_sample
#> [1] 15

Fit and predict

fit <- fit_hybridPLS(
  prep$predictor_train,
  prep$response_train,
  n_iter = 3,
  lambda = 1e-3,
  validation_data = list(
    W_test = prep$predictor_test,
    y_test = prep$response_test
  )
)

fit
#> Hybrid Penalized PLS model
#>   Components (n_iter): 3
#>   Functional predictors: 1
#>   Lambda: 0.001
#>   Validation RMSE by component:
#>     0.5779, 0.3936, 0.3822
preds <- predict(fit, prep$predictor_test)
rmse <- sqrt(mean((prep$response_test - preds)^2))
rmse
#> [1] 0.3822361

Choosing the number of components

cv <- cv_fit_hybridPLS(
  prep$predictor_train,
  prep$response_train,
  n_iter = 4,
  lambda = 1e-3,
  n_fold = 3,
  seed = 1
)
cv$rmse_by_component
#> [1] 0.5643767 0.4480987 0.4290852 0.4529231
cv$best_n_iter
#> [1] 3

Session info

sessionInfo()
#> R version 4.5.0 (2025-04-11 ucrt)
#> Platform: x86_64-w64-mingw32/x64
#> Running under: Windows 11 x64 (build 26200)
#> 
#> Matrix products: default
#>   LAPACK version 3.12.1
#> 
#> locale:
#> [1] LC_COLLATE=C                          
#> [2] LC_CTYPE=English_United States.utf8   
#> [3] LC_MONETARY=English_United States.utf8
#> [4] LC_NUMERIC=C                          
#> [5] LC_TIME=English_United States.utf8    
#> 
#> time zone: America/Los_Angeles
#> tzcode source: internal
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#> [1] FSHybridPLS_0.1.0
#> 
#> loaded via a namespace (and not attached):
#>  [1] cli_3.6.5          knitr_1.50         rlang_1.1.6        xfun_0.52         
#>  [5] KernSmooth_2.23-26 mclust_6.1.1       fds_1.8            deSolve_1.40      
#>  [9] jsonlite_2.0.0     hdrcde_3.4         RCurl_1.98-1.17    colorspace_2.1-1  
#> [13] htmltools_0.5.8.1  pracma_2.4.4       sass_0.4.10        rmarkdown_2.29    
#> [17] grid_4.5.0         evaluate_1.0.4     jquerylib_0.1.4    bitops_1.0-9      
#> [21] MASS_7.3-65        ks_1.15.1          fastmap_1.2.0      yaml_2.3.10       
#> [25] mvtnorm_1.3-3      lifecycle_1.0.5    rainbow_3.8        cluster_2.1.8.1   
#> [29] compiler_4.5.0     fda_6.3.0          lattice_0.22-6     digest_0.6.37     
#> [33] R6_2.6.1           splines_4.5.0      pcaPP_2.0-5        bslib_0.9.0       
#> [37] Matrix_1.7-3       tools_4.5.0        cachem_1.1.0

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.