Authors

  1. Hendra H. Dukalang ()
  2. Bambang Widjanarko Otok ()
  3. Purhadi ()

Resource

Data will be made available on request

Endogenous Laten Variables

η Behavioral Intention

Endogenous Laten Variables

ξ1 Performance expectations
ξ2 Business expectations
ξ3 Social influence
ξ4 Facility conditions

Library Packages

Before we start the analysis, here are some packages that are required to perform data analysis using Multivariate Adaptive Regression Spline (MARSPLS). However, we must ensure that all packages are installed so we can call the packages as follows.

library(ggplot2)
library(lmtest)
library(car)
library(earth)

#Call syntax of related functions
source("Score Latent Variable Estimation Function.R")

Input Data

#load data
data_utaut = read.csv("Hasil Kuisioner E-Wallet.csv", sep=";")
n = nrow(data_utaut)
head(data_utaut)
##   EK1 EK2 EK3 EK4 EU1 EU2 EU3 EU4 PS1 PS2 PS3 PS4 KF1 KF2 KF3 KF4 NB1 NB2 NB3
## 1   5   5   5   5   5   4   5   5   5   5   5   3   5   5   5   5   5   5   4
## 2   5   5   5   5   5   5   5   5   5   5   5   5   5   5   5   5   5   5   5
## 3   5   4   4   4   5   5   4   5   3   3   4   3   4   5   4   4   3   4   4
## 4   5   5   5   4   5   5   5   5   2   3   4   4   5   5   5   4   3   3   2
## 5   4   4   3   4   5   4   3   4   2   3   3   1   5   4   5   4   3   4   3
## 6   5   5   4   5   5   5   5   5   3   5   5   3   5   5   5   3   5   5   5
##   NB4
## 1   4
## 2   5
## 3   4
## 4   4
## 5   3
## 6   5

Estimating latent variable score

# Score Latent Variable
est=est_LVS(data_utaut)

xi=est$ksi
eta=est$eta

ksi1 = xi[,1]
ksi2 = xi[,2]
ksi3 = xi[,3]
ksi4 = xi[,4]
eta = eta
  
cat("\nScore Latent Variable\n")
## 
## Score Latent Variable
score = cbind(xi,eta)
colnames(score) = c(variable.names(xi),"η")
head(score)
##              ξ1         ξ2         ξ3         ξ4          η
## [1,]  0.9211893  0.4783715  1.1280358  0.9581119  0.5632644
## [2,]  0.9211893  0.9168385  1.6398722  0.9581119  1.2796490
## [3,] -0.4053724  0.4418537 -0.2245001 -0.3625242 -0.4204520
## [4,]  0.6128363  0.9168385 -0.1705984  0.6078286 -1.4607742
## [5,] -1.3326322 -0.7801609 -1.2953708  0.0730969 -1.1368366
## [6,]  0.4533420  0.9168385  0.7240028  0.2575452  1.2796490
cat("\n\nFactor Loading\n")
## 
## 
## Factor Loading
load.fak = est$loading
print(load.fak)
##           ξ1        ξ2        ξ3        ξ4         η
## λ1 0.8010378 0.8122458 0.7590981 0.7801763 0.8435768
## λ2 0.8204748 0.8568206 0.8591629 0.8516156 0.8152430
## λ3 0.7889583 0.8637763 0.8217405 0.8631266 0.8653736
## λ4 0.6014878 0.7177231 0.8353661 0.6545402 0.8275223

Linearity Detection

The Ramsey RESET test is an effective instrument for identifying misspecification in regression models, particularly concerning nonlinearity. If the model is determined to be nonlinear, it is essential to modify it by incorporating additional variables or exploring a more suitable data transformation.

ggplot(data.frame(ksi1, eta), aes(x = ksi1, y = eta)) +
  geom_point(shape = 21, colour = "blue",fill = "blue", size = 2.5) +
  labs(title = expression(paste("Scatterplot of ", eta, " vs ", xi[1])), 
       x = expression(xi[1]),
       y = expression(eta)) +
  theme_minimal() + 
  theme(plot.title = element_text(hjust = 0.5,size = 16, face = "bold"))

ggplot(data.frame(ksi2, eta), aes(x = ksi2, y = eta)) +
  geom_point(shape = 21, colour = "blue",fill = "blue", size = 2.5) +
  labs(title = expression(paste("Scatterplot of ", eta, " vs ", xi[2])), 
       x = expression(xi[2]),
       y = expression(eta)) +
  theme_minimal() + 
  theme(plot.title = element_text(hjust = 0.5,size = 16, face = "bold"))

ggplot(data.frame(ksi3, eta), aes(x = ksi3, y = eta)) +
  geom_point(shape = 21, colour = "blue",fill = "blue", size = 2.5) +
  labs(title = expression(paste("Scatterplot of ", eta, " vs ", xi[3])), 
       x = expression(xi[3]),
       y = expression(eta)) +
  theme_minimal() + 
  theme(plot.title = element_text(hjust = 0.5,size = 16, face = "bold"))

ggplot(data.frame(ksi4, eta), aes(x = ksi4, y = eta)) +
  geom_point(shape = 21, colour = "blue",fill = "blue", size = 2.5) +
  labs(title = expression(paste("Scatterplot of ", eta, " vs ", xi[4])), 
       x = expression(xi[4]),
       y = expression(eta)) +
  theme_minimal() + 
  theme(plot.title = element_text(hjust = 0.5,size = 16, face = "bold"))

#Linearity Test
cat("\nLinearity Test of η vs ξ1\n")
## 
## Linearity Test of η vs ξ1
reset(eta~ksi1)
## 
##  RESET test
## 
## data:  eta ~ ksi1
## RESET = 6.1373, df1 = 2, df2 = 381, p-value = 0.00238
cat("\nLinearity Test of η vs ξ2\n")
## 
## Linearity Test of η vs ξ2
reset(eta~ksi2)
## 
##  RESET test
## 
## data:  eta ~ ksi2
## RESET = 3.8642, df1 = 2, df2 = 381, p-value = 0.02181
cat("\nLinearity Test of η vs ξ3\n")
## 
## Linearity Test of η vs ξ3
reset(eta~ksi3)
## 
##  RESET test
## 
## data:  eta ~ ksi3
## RESET = 6.5776, df1 = 2, df2 = 381, p-value = 0.001555
cat("\nLinearity Test of η vs ξ4\n")
## 
## Linearity Test of η vs ξ4
reset(eta~ksi4)
## 
##  RESET test
## 
## data:  eta ~ ksi4
## RESET = 3.8637, df1 = 2, df2 = 381, p-value = 0.02182
cat("\nLinearity Test of η vs ξ1,ξ2,ξ3,ξ4\n")
## 
## Linearity Test of η vs ξ1,ξ2,ξ3,ξ4
reset(formula = eta ~ ksi1 + ksi2 + ksi3 + ksi4, power = 2, type = "fitted")
## 
##  RESET test
## 
## data:  eta ~ ksi1 + ksi2 + ksi3 + ksi4
## RESET = 3.9548, df1 = 1, df2 = 379, p-value = 0.04746

PLS SEM Model

PLS is an iterative algorithm that breaks down the measurement model blocks and, in the next step, estimates the path coefficients in the structural model.

reg1 = lm(eta ~ ksi1 + ksi2 + ksi3 + ksi4)
summary(reg1)
## 
## Call:
## lm(formula = eta ~ ksi1 + ksi2 + ksi3 + ksi4)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.98399 -0.46419  0.08742  0.48245  2.79007 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -2.650e-16  3.776e-02   0.000  1.00000    
## ksi1         1.008e-01  5.322e-02   1.894  0.05894 .  
## ksi2         2.424e-01  5.812e-02   4.170 3.77e-05 ***
## ksi3         3.045e-01  4.229e-02   7.201 3.23e-12 ***
## ksi4         2.055e-01  5.317e-02   3.866  0.00013 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.741 on 380 degrees of freedom
## Multiple R-squared:  0.4567, Adjusted R-squared:  0.451 
## F-statistic: 79.86 on 4 and 380 DF,  p-value: < 2.2e-16

MARSPLS

MARSPLS is an extension of the partial least squares structural equation model (PLS-SEM) designed for scenarios where the relationship between latent variable scores is nonlinear or indeterminate.

nilai_nk = c()
nilai_degree = c()
nilai_minspan = c()
nilai_gcv = c()
nilai_rsq = c()
for (i in c(9,13,17)){
  for (j in 1:3){
    for (k in 1:3){
      a = earth(x=xi,y=eta, nk=i,
                minspan=k,endspan=k, degree=j, penalty=-1, pmethod="none")
      nilai_nk = c(nilai_nk,a$nk)
      nilai_degree = c(nilai_degree,j)
      nilai_minspan = c(nilai_minspan,k)
      nilai_gcv = c(nilai_gcv,a$gcv)
      nilai_rsq = c(nilai_rsq,a$rsq)
    }
  }
}

optimumGCVMars=cbind(nilai_nk, nilai_degree, nilai_minspan,
                     nilai_gcv,nilai_rsq)

#sorting the minimum GCV values
GCVmin1=optimumGCVMars[order(optimumGCVMars[,ncol(optimumGCVMars)],decreasing = TRUE),]
cat("\nOrder Minimum GCV:\n")
## 
## Order Minimum GCV:
GCVmin1
##       nilai_nk nilai_degree nilai_minspan nilai_gcv nilai_rsq
##  [1,]       17            3             1 0.4580398 0.5407673
##  [2,]       17            3             2 0.4595267 0.5392766
##  [3,]       17            2             2 0.4603609 0.5384402
##  [4,]       17            2             1 0.4605128 0.5382879
##  [5,]       17            3             3 0.4626696 0.5361256
##  [6,]       17            2             3 0.4649667 0.5338224
##  [7,]       13            3             2 0.4763623 0.5223972
##  [8,]       13            3             1 0.4764795 0.5222796
##  [9,]       13            3             3 0.4772823 0.5214748
## [10,]       13            2             2 0.4779725 0.5207828
## [11,]       13            2             1 0.4782670 0.5204876
## [12,]       13            2             3 0.4785700 0.5201837
## [13,]       17            1             2 0.4894849 0.5092404
## [14,]       17            1             3 0.4897877 0.5089368
## [15,]       17            1             1 0.4916520 0.5070677
## [16,]        9            2             2 0.4996054 0.4990935
## [17,]        9            3             2 0.4996054 0.4990935
## [18,]        9            2             1 0.4998353 0.4988630
## [19,]        9            3             1 0.4998353 0.4988630
## [20,]        9            2             3 0.5001736 0.4985238
## [21,]        9            3             3 0.5001736 0.4985238
## [22,]       13            1             1 0.5011985 0.4974963
## [23,]       13            1             2 0.5016551 0.4970385
## [24,]       13            1             3 0.5019854 0.4967073
## [25,]        9            1             1 0.5107132 0.4879569
## [26,]        9            1             2 0.5108536 0.4878161
## [27,]        9            1             3 0.5109255 0.4877440
best = as.data.frame(t(GCVmin1[1,]))
model_best = earth(x=xi,y=eta, nk=best$nilai_nk,
                   minspan=best$nilai_minspan,endspan=best$nilai_minspan, 
                   degree=best$nilai_degree, penalty=-1)

cat("\nSummary of Basis Function:\n")
## 
## Summary of Basis Function:
summary(model_best, style = "bf")
## Call: earth(x=xi, y=eta, degree=best$nilai_degree, nk=best$nilai_nk,
##             minspan=best$nilai_minspan, endspan=best$nilai_minspan, penalty=-1)
## 
## eta =
##   -1.232224
##   -   0.217952 * bf1
##   +  0.3002871 * bf2
##   -  0.6868161 * bf3
##   +  0.2694033 * bf4
##   -   1.137398 * bf5
##   +  0.2076821 * bf6
##   + 0.07866258 * bf7 * bf1
##   +   4.760677 * bf8 * bf1
##   +  0.2545884 * bf9 * bf3
##   - 0.01166664 * bf10 * bf3
##   -   7.249754 * bf11 * bf4
##   + 0.08063738 * bf12 * bf4
##   +  0.9861144 * bf10 * bf3 * bf13
##   +    1.27991 * bf10 * bf3 * bf14
##   -   1.263136 * bf10 * bf3 * bf15
## 
##    bf1  h(-0.577095-ξ2)
##    bf2  h(ξ2--0.577095)
##    bf3  h(-0.574144-ξ3)
##    bf4  h(ξ3--0.574144)
##    bf5  h(-3.10291-ξ4)
##    bf6  h(ξ4--3.10291)
##    bf7  h(0.453342-ξ1)
##    bf8  h(ξ1-0.453342)
##    bf9  h(-1.78984-ξ1)
##   bf10  h(ξ1--1.78984)
##   bf11  h(-2.33084-ξ2)
##   bf12  h(ξ2--2.33084)
##   bf13  h(ξ4--1.24754)
##   bf14  h(-1.24754-ξ4)
##   bf15  h(ξ4--0.461635)
## 
## Selected 16 of 16 terms, and 4 of 4 predictors
## Termination condition: Reached nk 17
## Importance: ξ2, ξ3, ξ4, ξ1
## Number of terms at each degree of interaction: 1 6 6 3
## GCV 0.4580398    RSS 176.3453    GRSq 0.5407673    RSq 0.5407673
cat("\nSummary The Best MARS Model:\n")
## 
## Summary The Best MARS Model:
summary(model_best)
## Call: earth(x=xi, y=eta, degree=best$nilai_degree, nk=best$nilai_nk,
##             minspan=best$nilai_minspan, endspan=best$nilai_minspan, penalty=-1)
## 
##                                                      coefficients
## (Intercept)                                            -1.2322243
## h(-0.577095-ξ2)                                        -0.2179520
## h(ξ2- -0.577095)                                        0.3002871
## h(-0.574144-ξ3)                                        -0.6868161
## h(ξ3- -0.574144)                                        0.2694033
## h(-3.10291-ξ4)                                         -1.1373977
## h(ξ4- -3.10291)                                         0.2076821
## h(0.453342-ξ1) * h(-0.577095-ξ2)                        0.0786626
## h(ξ1-0.453342) * h(-0.577095-ξ2)                        4.7606770
## h(-1.78984-ξ1) * h(-0.574144-ξ3)                        0.2545884
## h(ξ1- -1.78984) * h(-0.574144-ξ3)                      -0.0116666
## h(-2.33084-ξ2) * h(ξ3- -0.574144)                      -7.2497538
## h(ξ2- -2.33084) * h(ξ3- -0.574144)                      0.0806374
## h(ξ1- -1.78984) * h(-0.574144-ξ3) * h(ξ4- -1.24754)     0.9861144
## h(ξ1- -1.78984) * h(-0.574144-ξ3) * h(-1.24754-ξ4)      1.2799101
## h(ξ1- -1.78984) * h(-0.574144-ξ3) * h(ξ4- -0.461635)   -1.2631365
## 
## Selected 16 of 16 terms, and 4 of 4 predictors
## Termination condition: Reached nk 17
## Importance: ξ2, ξ3, ξ4, ξ1
## Number of terms at each degree of interaction: 1 6 6 3
## GCV 0.4580398    RSS 176.3453    GRSq 0.5407673    RSq 0.5407673
cat("\nEstimate variable importances:\n")
## 
## Estimate variable importances:
evimp(model_best)
##    nsubsets   gcv    rss
## ξ2       15 100.0  100.0
## ξ3       14  65.5   65.5
## ξ4       13  47.4   47.4
## ξ1       11  38.2   38.2
# Prediction
eta_pred <- predict(model_best)

# Calculate MSE and RMSE
MSE <- mean((eta - eta_pred)^2)
RMSE <- sqrt(MSE)

# Calculate AIC, AICc, dan BIC
k_mars=length(coef(model_best)[coef(model_best)!=0])-1

R2_mars <- summary(model_best)$rsq  # R-squared
R2_adj <- 1 - ((1 - R2_mars) * (n - 1) / (n - k_mars - 1))
RSS <- sum((eta - eta_pred)^2)
AIC <- n * log(RSS/n) + 2*k
AICc <- AIC + (2*k_mars*(k_mars+1))/(n-k_mars-1)  # AIC correction for small samples
BIC <- n * log(RSS/n) + log(n) * k_mars

# Show Accuracy
Akurasi = as.matrix(c(MSE,RMSE,R2_mars,R2_adj,AIC,AICc,BIC),ncol=1)
colnames(Akurasi) = "Goodness of Fit"
rownames(Akurasi) = c("MSE","RMSE","R2_MARS","R2_Adj","AIC","AICc","BIC")
cat("\nAkurasi Model\n")
## 
## Akurasi Model
print(Akurasi)
##         Goodness of Fit
## MSE           0.4580398
## RMSE          0.6767864
## R2_MARS       0.5407673
## R2_Adj        0.5220994
## AIC        -294.6076582
## AICc       -293.3068452
## BIC        -211.3090082
# wich = 1 untuk Model Selection dan wich = 4 untuk Residual 
plot(model_best, which = 1)

Save Output of MARSPLS

Save the MARSPLS model output into several csv files to facilitate further analysis.

# Save Output of MARSPLS Model 
write.csv(model_best$bx,"Basis Function.csv", row.names = FALSE)
write.csv(model_best$coefficients,"Coefficients of MARSPLS.csv",
          row.names = FALSE)
result = cbind(ksi1,ksi2,ksi3,ksi4,eta,model_best$bx,model_best$fitted.values,model_best$residuals)
colnames(result) = c("ξ1","ξ2","ξ3","ξ4","η",variable.names(model_best$bx),"fitted","residual")
write.csv(result,"Result MARSPLS.csv", row.names = FALSE)