Data analysis - Soft Robot Walker Study

Author

Julius Fenn

1 Notes

2 global variables

Define your global variables (can take some time to run):

## global variables
runIRTmodels <- FALSE

runMplusLCA <- FALSE
## set to lower values to reduce compilation time: 
nRep_def = 100 # 100
n.lambda_def = 40 # 40
LCArunsDef = 8 # 10

3 load raw data

# sets the directory of location of this script as the current directory
# setwd(dirname(rstudioapi::getSourceEditorContext()$path))

### load packages
require(pacman)
p_load('tidyverse', 'jsonlite',
       'stargazer',  'DT', 'psych',
       'writexl', 'moments', 'lavaan', 'semPlot', 'mirt', 'MplusAutomation',
       'afex', 'emmeans', 'jtools',
       'car',
       'text2sdg', 'sentimentr')


setwd("../01_dataPreperation/outputs")
dat <- read_rds(file = "questionnaire.rds")


### load functions
setwd("../../../functions")
for(i in 1:length(dir())){
  # print(dir()[i])
  source(dir()[i], encoding = "utf-8")
}

rm(i)


### summary function
data_summary <- function(data, varname, groupnames){
  require(plyr)
  summary_func <- function(x, col){
    c(mean = mean(x[[col]], na.rm=TRUE),
      se = sd(x[[col]], na.rm=TRUE) / sqrt(length(x[[col]])))
  }
  data_sum<-ddply(data, groupnames, .fun=summary_func,
                  varname)
  data_sum <- plyr::rename(data_sum, c("mean" = varname))
  return(data_sum)
}

4 Remove persons how participants two times

tmp <- names(table(dat$PROLIFIC_PID))[table(dat$PROLIFIC_PID) >= 2]
tmp; length(tmp)
character(0)
[1] 0
dat[dat$PROLIFIC_PID %in% tmp[1],]
 [1] ID                               meta.userAgent                  
 [3] meta.platform                    meta.language                   
 [5] meta.locale                      meta.timeZone                   
 [7] meta.timezoneOffset              meta.screen_width               
 [9] meta.screen_height               meta.scroll_width               
[11] meta.scroll_height               meta.window_innerWidth          
[13] meta.window_innerHeight          meta.devicePixelRatio           
[15] PROLIFIC_PID                     framingCondition                
[17] sociodemo_gender                 sociodemo_priorExperience       
[19] sociodemo_residency              sociodemo_education             
[21] feedback_critic                  attCheck_text                   
[23] sociodemo_universityAffiliation  sociodemo_universityField       
[25] reflection_ecological            reflection_social               
[27] reflection_economic              EcologicalDimension-1           
[29] EcologicalDimension-3            EcologicalDimension-4           
[31] EcologicalDimension-2            Bioinspiration-VRtN1            
[33] Bioinspiration-PN4               Bioinspiration-VRtN4r           
[35] Bioinspiration-IPI1              Bioinspiration-PN2r             
[37] Bioinspiration-VRtN2             Bioinspiration-IPI2r            
[39] Bioinspiration-PN3               Bioinspiration-IPI3             
[41] Bioinspiration-IPI4              Bioinspiration-VRtN3            
[43] Bioinspiration-PN1               evalInf-6                       
[45] evalInf-5                        evalInf-8                       
[47] evalInf-2                        evalInf-3                       
[49] evalInf-4                        evalInf-10                      
[51] evalInf-7                        evalInf-1                       
[53] evalInf-9                        excitingDesign                  
[55] entertainingDesign               boringDesign                    
[57] usefulDesign                     unnecessaryDesign               
[59] unimportantDesign                excitingTopic                   
[61] entertainingTopic                boringTopic                     
[63] usefulTopic                      unnecessaryTopic                
[65] unimportantTopic                 GAToRS-4pp                      
[67] GAToRS-3sp                       GAToRS-4pn                      
[69] GAToRS-5pp                       GAToRS-1pp                      
[71] GAToRS-3pp                       GAToRS-4sp                      
[73] GAToRS-2pn                       GAToRS-2sp                      
[75] GAToRS-1sn                       GAToRS-3pn                      
[77] GAToRS-5pn                       GAToRS-1pn                      
[79] GAToRS-4sn                       GAToRS-5sn                      
[81] GAToRS-5sp                       GAToRS-2pp                      
[83] GAToRS-1sp                       GAToRS-3sn                      
[85] GAToRS-2sn                       dummy_informedconsent           
[87] commCheck                        feedback_conscientiousCompletion
[89] sociodemo_age                    whichItemsFirst                 
[91] socio_age                        socio_sex                       
[93] socio_ethnicity                  socio_student                   
[95] socio_employment                 total_min_prolific              
<0 Zeilen> (oder row.names mit Länge 0)
## keep only first participation
keep_rows <- do.call(rbind, lapply(tmp, function(id) {
  rows <- dat[dat$PROLIFIC_PID == id, ]
  rows[which.min(as.numeric(rownames(rows))), , drop = FALSE]
}))



nrow(dat)
[1] 298
dat <- dat[!dat$PROLIFIC_PID %in% tmp, ]
dat <- rbind(dat, keep_rows)
nrow(dat)
[1] 298

5 Descriptive Statistics

To describe sample:

psych::describe(dat[, c("sociodemo_age")])
   vars   n  mean    sd median trimmed   mad min max range  skew kurtosis   se
X1    1 298 47.08 15.32     49    47.2 17.79  19  84    65 -0.09    -1.09 0.89
table(dat$sociodemo_gender)

   female      male nonbinary      none 
      153       143         1         1 
table(dat$sociodemo_gender) / nrow(dat)

     female        male   nonbinary        none 
0.513422819 0.479865772 0.003355705 0.003355705 
prop.table(table(dat$sociodemo_gender))

     female        male   nonbinary        none 
0.513422819 0.479865772 0.003355705 0.003355705 
table(dat$sociodemo_priorExperience)

      no not_sure yes_some yes_well 
     238       17       37        6 
table(dat$sociodemo_priorExperience) / nrow(dat)

        no   not_sure   yes_some   yes_well 
0.79865772 0.05704698 0.12416107 0.02013423 
table(dat$socio_sex) # from Prolific

Female   Male 
   155    143 
table(dat$socio_sex, dat$sociodemo_gender)
        
         female male nonbinary none
  Female    153    1         0    1
  Male        0  142         1    0
table(dat$socio_employment)

                                            DATA_EXPIRED 
                                                      28 
            Due to start a new job within the next month 
                                                       4 
                                               Full-Time 
                                                     131 
Not in paid work (e.g. homemaker', 'retired or disabled) 
                                                      55 
                                                   Other 
                                                      10 
                                               Part-Time 
                                                      54 
                            Unemployed (and job seeking) 
                                                      16 
table(dat$socio_ethnicity)

Asian Black Mixed Other White 
   23     9    11     8   247 

To describe study conditions:

table(dat$framingCondition)

 bio-inspired tech-inspired 
          160           138 

To describe length of study:

psych::describe(dat[, c("total_min_prolific")])
   vars   n  mean   sd median trimmed  mad   min   max range skew kurtosis   se
X1    1 298 27.63 9.62  24.98   26.21 6.98 14.65 75.57 60.92 1.72     3.92 0.56
hist(dat$total_min_prolific)
abline(v = mean(dat$total_min_prolific))

To describe conditions:

table(dat$framingCondition, dat$whichItemsFirst)
               
                bioinspired sustainable
  bio-inspired           78          82
  tech-inspired          77          61

5.1 Check for differences between conditions

## -----------------------------
## Descriptive statistics
## -----------------------------

# Age
mean(dat$sociodemo_age, na.rm = TRUE)
[1] 47.08389
sd(dat$sociodemo_age, na.rm = TRUE)
[1] 15.31893
summary(dat$sociodemo_age)   # includes median
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  19.00   33.00   49.00   47.08   60.00   84.00 
# Gender counts + proportions
table(dat$sociodemo_gender)

   female      male nonbinary      none 
      153       143         1         1 
prop.table(table(dat$sociodemo_gender))

     female        male   nonbinary        none 
0.513422819 0.479865772 0.003355705 0.003355705 
# Prior experience counts + proportions
table(dat$sociodemo_priorExperience)

      no not_sure yes_some yes_well 
     238       17       37        6 
prop.table(table(dat$sociodemo_priorExperience))

        no   not_sure   yes_some   yes_well 
0.79865772 0.05704698 0.12416107 0.02013423 
## -----------------------------
## Check for differences between framing conditions
## -----------------------------
# 1. Age differences across conditions (ANOVA)
anova_age <- aov(sociodemo_age ~ framingCondition, data = dat)
summary(anova_age)
                  Df Sum Sq Mean Sq F value Pr(>F)
framingCondition   1     50   49.53    0.21  0.647
Residuals        296  69647  235.30               
# Also check assumptions
shapiro.test(residuals(anova_age))

    Shapiro-Wilk normality test

data:  residuals(anova_age)
W = 0.95851, p-value = 1.702e-07
car::leveneTest(sociodemo_age ~ framingCondition, data = dat)  # requires car package
Levene's Test for Homogeneity of Variance (center = median)
       Df F value Pr(>F)
group   1  0.0119 0.9133
      296               
# 2. Gender differences across conditions (Chi-square)
gender_table <- table(dat$framingCondition, dat$sociodemo_gender)
chisq.test(gender_table)
Warning in chisq.test(gender_table): Chi-Quadrat-Approximation kann inkorrekt
sein

    Pearson's Chi-squared test

data:  gender_table
X-squared = 1.8882, df = 3, p-value = 0.5959
# 3. Prior experience differences across conditions (Chi-square)
experience_table <- table(dat$framingCondition, dat$sociodemo_priorExperience)
chisq.test(experience_table)
Warning in chisq.test(experience_table): Chi-Quadrat-Approximation kann
inkorrekt sein

    Pearson's Chi-squared test

data:  experience_table
X-squared = 4.3901, df = 3, p-value = 0.2223

5.2 remove participants with insufficient effort responding (IER)

insufficient effort responding: respondents provide careless or random responses to survey items

5.2.1 IER: set up dataset

dat_IER <- data.frame(PROLIFIC_PID = dat$PROLIFIC_PID)


#### slow persons total duration
dat_IER$slowTD <- 0

out <- boxplot.stats(dat$total_min_prolific)$out
out_ind <- which(dat$total_min_prolific %in% c(out))

dat_IER$slowTD[dat_IER$PROLIFIC_PID %in% dat$PROLIFIC_PID[out_ind]] <- 1


#### careless respondents based on
# > intra-individual response variability
# > zero SD (all answers equal)
# > Mahalanobis distance (multivariate outliers)
# > compute SD over rows

rowVars <- function(x, na.rm=FALSE) {
  # Vectorised version of variance filter
  rowSums((x - rowMeans(x, na.rm=na.rm))^2, na.rm=na.rm) / (ncol(x) - 1)
}


scales_regEX <- c("^EcologicalDimension",
            "Bioinspiration.*PN",
             "Bioinspiration.*VRtN",
             "Bioinspiration.*IPI",
            "^GAToRS.*pp$",
            "^GAToRS.*pn$",
            "^GAToRS.*sp$",
            "^GAToRS.*sn$")


mat_IIRV <- matrix(data = 0, nrow = nrow(dat), ncol = length(scales_regEX)+1)
mat_IIRV[,1] <- dat$PROLIFIC_PID

mat_zero <- matrix(data = 0, nrow = nrow(dat), ncol = length(scales_regEX)+1)
mat_zero[,1] <- dat$PROLIFIC_PID

mat_MD <- matrix(data = 0, nrow = nrow(dat), ncol = length(scales_regEX)+1)
mat_MD[,1] <- dat$PROLIFIC_PID


h = 2
for(e in scales_regEX){
  tmp <- dat[, str_subset(string = colnames(dat), pattern = e)]
  tmp <- tmp[, str_subset(string = colnames(tmp), pattern = "^mean_", negate = TRUE)]

  ## by intra-individual response variability
  tmp_SD <- sqrt(rowVars(tmp))
  out <- boxplot.stats(tmp_SD)$out
  mat_IIRV[,h][mat_IIRV[,1] %in% dat$PROLIFIC_PID[tmp_SD %in% out]] <- 1

  ## zero SD (all answers equal)
  mat_zero[,h][mat_zero[,1] %in% dat$PROLIFIC_PID[tmp_SD == 0]] <- 1



  ## by Mahalanobis distance (multivariate outliers)
  tmp$mahal <- mahalanobis(tmp, colMeans(tmp), cov(tmp))
  tmp$p_mahal <- pchisq(tmp$mahal, df=ncol(tmp)-2, lower.tail=FALSE)
  mat_MD[,h][mat_MD[,1] %in% dat$PROLIFIC_PID[tmp$p_mahal %in% tmp$p_mahal[tmp$p_mahal < .001]]] <- 1


 h = h + 1
}


labels <- str_replace_all(string = scales_regEX, pattern = "\\W+", replacement = "")

dat_IIRV <- as.data.frame(mat_IIRV)
colnames(dat_IIRV) <- c("PROLIFIC_PID",
                        labels)
dat_zero <- as.data.frame(mat_zero)
colnames(dat_zero) <- c("PROLIFIC_PID",
                        labels)
dat_MD <- as.data.frame(mat_MD)
colnames(dat_MD) <- c("PROLIFIC_PID",
                      labels)



dat_IIRV[,labels] <- lapply(dat_IIRV[,labels], as.numeric)
dat_zero[,labels] <- lapply(dat_zero[,labels], as.numeric)
dat_MD[,labels] <- lapply(dat_MD[,labels], as.numeric)


## ADD by intra-individual response variability
table(rowSums(dat_IIRV[,labels]))

  0   1   2   3 
268  27   2   1 
tmp <- rowSums(dat_IIRV[,labels]) >= 3
dat_IER$IIRV <- 0
dat_IER$IIRV[dat_IER$PROLIFIC_PID %in% dat_IIRV$PROLIFIC_PID[tmp]] <- 1

## ADD zero SD (all answers equal)
table(rowSums(dat_zero[,labels]))

  0   1   2   3   4   5   6   7   8 
131  98  41  19   4   2   1   1   1 
tmp <- rowSums(dat_zero[,labels]) >= 3
dat_IER$zero <- 0
dat_IER$zero[dat_IER$PROLIFIC_PID %in% dat_zero$PROLIFIC_PID[tmp]] <- 1


## ADD by Mahalanobis distance (multivariate outliers)
table(rowSums(dat_MD[,labels]))

  0   1   2   3 
248  43   6   1 
tmp <- rowSums(dat_MD[,labels]) >= 2
dat_IER$MD <- 0
dat_IER$MD[dat_IER$PROLIFIC_PID %in% dat_MD$PROLIFIC_PID[tmp]] <- 1

5.2.2 IER: investigate

sum(rowSums(dat_IER[,2:ncol(dat_IER)]) >= 2)
[1] 7
dat_IER[rowSums(dat_IER[,2:ncol(dat_IER)]) >= 2,]
                PROLIFIC_PID slowTD IIRV zero MD
3   5bb7b83ab791890001f4fd90      1    0    1  0
21  5ace82e135eccf0001a11c96      0    0    1  1
34  682b3f63d0e2c4eff64fe664      1    0    1  0
65  5718a9c4dd9ef10013df01f0      0    1    0  1
126 665ba5fad0a8c603ab8b5242      1    0    1  1
158 6730dedb32982b0bdf64d9c2      1    0    1  0
188 664de718b933e68528f6a979      1    0    0  1
## flag to delete
tmp_IDs <- dat_IER$PROLIFIC_PID[rowSums(dat_IER[,2:ncol(dat_IER)]) >= 2]
dat$flagDelete <- 0
dat$flagDelete[dat$PROLIFIC_PID %in% tmp_IDs] <- 1

 dat[dat$flagDelete == 1, str_subset(string = colnames(dat), pattern = "^EcologicalDimension")]
    EcologicalDimension-1 EcologicalDimension-3 EcologicalDimension-4
3                       7                     7                     5
21                      2                     3                     2
34                      6                     7                     4
65                      5                     6                     5
126                     7                     7                     7
158                     7                     7                     7
188                     7                     7                     6
    EcologicalDimension-2
3                       7
21                      5
34                      7
65                      6
126                     7
158                     7
188                     2
 dat[dat$flagDelete == 1, str_subset(string = colnames(dat), pattern = "^Bioinspiration.")]
    Bioinspiration-VRtN1 Bioinspiration-PN4 Bioinspiration-VRtN4r
3                      5                  5                     7
21                     1                  1                     4
34                     3                  6                     6
65                     1                  3                     6
126                    7                  6                     7
158                    6                  6                     7
188                    6                  6                     6
    Bioinspiration-IPI1 Bioinspiration-PN2r Bioinspiration-VRtN2
3                     7                   5                    4
21                    6                   7                    5
34                    6                   1                    6
65                    7                   4                    6
126                   7                   2                    6
158                   7                   6                    7
188                   7                   5                    6
    Bioinspiration-IPI2r Bioinspiration-PN3 Bioinspiration-IPI3
3                      7                  3                   7
21                     6                  1                   6
34                     6                  5                   6
65                     7                  5                   7
126                    7                  7                   7
158                    7                  6                   7
188                    5                  6                   3
    Bioinspiration-IPI4 Bioinspiration-VRtN3 Bioinspiration-PN1
3                     7                    6                  3
21                    6                    4                  1
34                    6                    7                  5
65                    7                    6                  4
126                   7                    7                  7
158                   7                    7                  6
188                   6                    6                  6

after visual inspection no removal of participants

6 Evaluation Scales

6.1 Overall EFA PES, PBS

Promax rotation, factoring method minimum residual, if scale is a likert scale less or equal than 7 answering options the EFA or parallel analysis is computed over a polychoric correlation to account for non-normality of data (see in detail R-Code “helperFunctions”)

#### Overall EFA
regExOverall <- "^Bioinspiration|^EcologicalDimension"


psych::cor.plot(r = cor(dat[, str_detect(string = colnames(dat),
                                                   pattern = regExOverall)]
                        , use = "pairwise.complete.obs"),
                upper = FALSE, xlas = 2, main = "Overall")

#> parallel analysis
tmp_parallelAnalysis <- dimensionalityTest(label = "Overall",
                             regEx = regExOverall, dataset = dat)
Warning in fa.stats(r = r, f = f, phi = phi, n.obs = n.obs, np.obs = np.obs, :
The estimated weights for the factor scores are probably incorrect.  Try a
different factor score estimation method.
Warning in fa.stats(r = r, f = f, phi = phi, n.obs = n.obs, np.obs = np.obs, :
The estimated weights for the factor scores are probably incorrect.  Try a
different factor score estimation method.

Parallel analysis suggests that the number of factors =  3  and the number of components =  3 
Overall 
Number of components:  3 
#> EFA
tmp_EFA <- explorativeFactorAnalysis(label = "Overall",
                                 regEx = regExOverall,
                                 dataset = dat, nfac = tmp_parallelAnalysis$nfact)
Warning in fa.stats(r = r, f = f, phi = phi, n.obs = n.obs, np.obs = np.obs, :
The estimated weights for the factor scores are probably incorrect.  Try a
different factor score estimation method.
tmp_EFA[[1]]
Factor Analysis using method =  minres
Call: fa(r = tmp_dat, nfactors = nfac, rotate = "promax", cor = "cor")
Standardized loadings (pattern matrix) based upon correlation matrix
                        MR2   MR1   MR3   h2   u2 com
EcologicalDimension-1 -0.05  0.13  0.80 0.71 0.29 1.1
EcologicalDimension-3  0.15 -0.12  0.83 0.69 0.31 1.1
EcologicalDimension-4 -0.09  0.17  0.62 0.47 0.53 1.2
EcologicalDimension-2  0.06 -0.12  0.89 0.74 0.26 1.0
Bioinspiration-VRtN1  -0.08  0.84 -0.03 0.65 0.35 1.0
Bioinspiration-PN4    -0.05  0.66  0.10 0.48 0.52 1.1
Bioinspiration-VRtN4r  0.58  0.27 -0.11 0.48 0.52 1.5
Bioinspiration-IPI1    0.86 -0.07  0.07 0.74 0.26 1.0
Bioinspiration-PN2r   -0.02 -0.32  0.00 0.11 0.89 1.0
Bioinspiration-VRtN2   0.41  0.49 -0.03 0.55 0.45 1.9
Bioinspiration-IPI2r   0.58 -0.26 -0.03 0.29 0.71 1.4
Bioinspiration-PN3    -0.10  0.84  0.00 0.66 0.34 1.0
Bioinspiration-IPI3    0.78  0.01  0.02 0.63 0.37 1.0
Bioinspiration-IPI4    0.75  0.00  0.09 0.62 0.38 1.0
Bioinspiration-VRtN3   0.61  0.24  0.03 0.56 0.44 1.3
Bioinspiration-PN1     0.01  0.85 -0.05 0.70 0.30 1.0

                       MR2  MR1  MR3
SS loadings           3.27 3.24 2.56
Proportion Var        0.20 0.20 0.16
Cumulative Var        0.20 0.41 0.57
Proportion Explained  0.36 0.36 0.28
Cumulative Proportion 0.36 0.72 1.00

 With factor correlations of 
     MR2  MR1  MR3
MR2 1.00 0.38 0.32
MR1 0.38 1.00 0.46
MR3 0.32 0.46 1.00

Mean item complexity =  1.2
Test of the hypothesis that 3 factors are sufficient.

df null model =  120  with the objective function =  8.49 with Chi Square =  2470.08
df of  the model are 75  and the objective function was  0.46 

The root mean square of the residuals (RMSR) is  0.03 
The df corrected root mean square of the residuals is  0.04 

The harmonic n.obs is  298 with the empirical chi square  61.37  with prob <  0.87 
The total n.obs was  298  with Likelihood Chi Square =  133.96  with prob <  3.4e-05 

Tucker Lewis Index of factoring reliability =  0.96
RMSEA index =  0.051  and the 90 % confidence intervals are  0.037 0.065
BIC =  -293.32
Fit based upon off diagonal values = 0.99
Measures of factor score adequacy             
                                                   MR2  MR1  MR3
Correlation of (regression) scores with factors   0.95 0.95 0.95
Multiple R square of scores with factors          0.90 0.90 0.90
Minimum correlation of possible factor scores     0.79 0.80 0.79

three factor structure, within bioinspiried dimensions no strong differences in overall answering patterns; 1 item is dysfunctional (negative correlated)

6.2 Descriptives, correlation plot, EFA, CFA for “Ecological Sustainability Scale (PES)”

Applied a self-written function for example to check the reliability and amount of explained variance for the first factor:

regEx <- "^EcologicalDimension"
nameVariable <- "Ecology"


sum(str_detect(string = colnames(dat), pattern = regEx))
[1] 4
tmp_dat <- na.omit(dat[,str_detect(string = colnames(dat), pattern = regEx)])


tmp <- CFAstats(dataset = tmp_dat, regularExp = regEx, labelLatent = str_remove(string = nameVariable, pattern = "mean_"), 
                showPlots = TRUE, 
                computeEFA = TRUE, 
                computeCFA = TRUE, 
                computeCFAMplus = FALSE)



descriptive statistics: 
                      Mean   SD Median CoeffofVariation Minimum Maximun
EcologicalDimension-1 5.46 1.32      6             0.24       2       7
EcologicalDimension-3 5.84 1.15      6             0.20       2       7
EcologicalDimension-4 5.34 1.31      5             0.25       1       7
EcologicalDimension-2 5.68 1.23      6             0.22       1       7
                      Lower Quantile Upper Quantile Skewness Kurtosis(-3)
EcologicalDimension-1              2              7    -0.73        -0.10
EcologicalDimension-3              2              7    -0.98         0.73
EcologicalDimension-4              1              7    -0.54        -0.14
EcologicalDimension-2              1              7    -1.04         0.92
                      KS-Test
EcologicalDimension-1       0
EcologicalDimension-3       0
EcologicalDimension-4       0
EcologicalDimension-2       0


variables under investigation:  EcologicalDimension1 EcologicalDimension3 EcologicalDimension4 EcologicalDimension2 

Cronbachs Alpha: 0.87 

Parallel analysis suggests that the number of factors =  1  and the number of components =  1 
Ecology 
Number of components:  1 



EFA factor loadings (1 factor solution): 

Loadings:
                     MR1  
EcologicalDimension1 0.869
EcologicalDimension3 0.870
EcologicalDimension4 0.710
EcologicalDimension2 0.888

                 MR1
SS loadings    2.803
Proportion Var 0.701
CFA summary and fit statistics: 
lavaan 0.6-19 ended normally after 18 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                         8

  Number of observations                           298

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                                 3.288       3.308
  Degrees of freedom                                 2           2
  P-value (Chi-square)                           0.193       0.191
  Scaling correction factor                                  0.994
    Yuan-Bentler correction (Mplus variant)                       

Model Test Baseline Model:

  Test statistic                               601.916     292.934
  Degrees of freedom                                 6           6
  P-value                                        0.000       0.000
  Scaling correction factor                                  2.055

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    0.998       0.995
  Tucker-Lewis Index (TLI)                       0.994       0.986
                                                                  
  Robust Comparative Fit Index (CFI)                         0.998
  Robust Tucker-Lewis Index (TLI)                            0.993

Loglikelihood and Information Criteria:

  Loglikelihood user model (H0)              -1659.391   -1659.391
  Scaling correction factor                                  1.881
      for the MLR correction                                      
  Loglikelihood unrestricted model (H1)      -1657.747   -1657.747
  Scaling correction factor                                  1.703
      for the MLR correction                                      
                                                                  
  Akaike (AIC)                                3334.782    3334.782
  Bayesian (BIC)                              3364.359    3364.359
  Sample-size adjusted Bayesian (SABIC)       3338.988    3338.988

Root Mean Square Error of Approximation:

  RMSEA                                          0.046       0.047
  90 Percent confidence interval - lower         0.000       0.000
  90 Percent confidence interval - upper         0.133       0.134
  P-value H_0: RMSEA <= 0.050                    0.411       0.408
  P-value H_0: RMSEA >= 0.080                    0.337       0.340
                                                                  
  Robust RMSEA                                               0.047
  90 Percent confidence interval - lower                     0.000
  90 Percent confidence interval - upper                     0.133
  P-value H_0: Robust RMSEA <= 0.050                         0.410
  P-value H_0: Robust RMSEA >= 0.080                         0.337

Standardized Root Mean Square Residual:

  SRMR                                           0.013       0.013

Parameter Estimates:

  Standard errors                             Sandwich
  Information bread                           Observed
  Observed information based on                Hessian

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  Ecology =~                                                            
    EcologclDmnsn1    1.000                               1.090    0.827
    EcologclDmnsn3    0.870    0.070   12.465    0.000    0.949    0.824
    EcologclDmnsn4    0.794    0.069   11.461    0.000    0.865    0.660
    EcologclDmnsn2    0.969    0.067   14.380    0.000    1.056    0.857

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .EcologclDmnsn1    0.550    0.091    6.024    0.000    0.550    0.316
   .EcologclDmnsn3    0.425    0.071    5.983    0.000    0.425    0.321
   .EcologclDmnsn4    0.971    0.136    7.146    0.000    0.971    0.565
   .EcologclDmnsn2    0.403    0.102    3.964    0.000    0.403    0.265
    Ecology           1.188    0.140    8.465    0.000    1.000    1.000



CFA first 6 Modification Indices: 
                    lhs op                  rhs    mi    epc sepc.lv sepc.all
11 EcologicalDimension1 ~~ EcologicalDimension4 3.276  0.105   0.105    0.144
14 EcologicalDimension3 ~~ EcologicalDimension2 3.276  0.112   0.112    0.270
13 EcologicalDimension3 ~~ EcologicalDimension4 1.277 -0.057  -0.057   -0.089
12 EcologicalDimension1 ~~ EcologicalDimension2 1.277 -0.081  -0.081   -0.171
15 EcologicalDimension4 ~~ EcologicalDimension2 0.442 -0.036  -0.036   -0.058
10 EcologicalDimension1 ~~ EcologicalDimension3 0.442 -0.041  -0.041   -0.085
   sepc.nox
11    0.144
14    0.270
13   -0.089
12   -0.171
15   -0.058
10   -0.085
des_tab <- tmp$desTable %>%
  as.data.frame() %>%
  select(Mean, SD, Skewness, `Kurtosis(-3)`, `KS-Test`)
stargazer(
  des_tab,
  summary = FALSE,
  rownames = TRUE,
  title = "Descriptive Statistics for Ecological Items",
  label = "tab:ecology_desc",
  digits = 2,
  table.placement = "ht!",
  font.size = "small"
)

% Table created by stargazer v.5.2.3 by Marek Hlavac, Social Policy Institute. E-mail: marek.hlavac at gmail.com
% Date and time: Do, Dez 18, 2025 - 11:02:31
\begin{table}[ht!] \centering 
  \caption{Descriptive Statistics for Ecological Items} 
  \label{tab:ecology_desc} 
\small 
\begin{tabular}{@{\extracolsep{5pt}} cccccc} 
\\[-1.8ex]\hline 
\hline \\[-1.8ex] 
 & Mean & SD & Skewness & Kurtosis(-3) & KS-Test \\ 
\hline \\[-1.8ex] 
EcologicalDimension-1 & $5.46$ & $1.32$ & $$-$0.73$ & $$-$0.10$ & $0$ \\ 
EcologicalDimension-3 & $5.84$ & $1.15$ & $$-$0.98$ & $0.73$ & $0$ \\ 
EcologicalDimension-4 & $5.34$ & $1.31$ & $$-$0.54$ & $$-$0.14$ & $0$ \\ 
EcologicalDimension-2 & $5.68$ & $1.23$ & $$-$1.04$ & $0.92$ & $0$ \\ 
\hline \\[-1.8ex] 
\end{tabular} 
\end{table} 
omega_results <- psych::omega(tmp_dat, nfactors = 1)  # or more if needed
omega_results
Omega 
Call: omegah(m = m, nfactors = nfactors, fm = fm, key = key, flip = flip, 
    digits = digits, title = title, sl = sl, labels = labels, 
    plot = plot, n.obs = n.obs, rotate = rotate, Phi = Phi, option = option, 
    covar = covar)
Alpha:                 0.87 
G.6:                   0.84 
Omega Hierarchical:    0.87 
Omega H asymptotic:    1 
Omega Total            0.87 

Schmid Leiman Factor loadings greater than  0.2 
                         g  F1*   h2   h2   u2 p2 com
EcologicalDimension-1 0.84      0.70 0.70 0.30  1   1
EcologicalDimension-3 0.82      0.67 0.67 0.33  1   1
EcologicalDimension-4 0.66      0.44 0.44 0.56  1   1
EcologicalDimension-2 0.85      0.73 0.73 0.27  1   1

With Sums of squares  of:
  g F1*  h2 
2.5 0.0 1.7 

general/max  1.53   max/min =   Inf
mean percent general =  1    with sd =  0 and cv of  0 
Explained Common Variance of the general factor =  1 

The degrees of freedom are 2  and the fit is  0.01 
The number of observations was  298  with Chi Square =  3.5  with prob <  0.17
The root mean square of the residuals is  0.02 
The df corrected root mean square of the residuals is  0.03
RMSEA index =  0.05  and the 90 % confidence intervals are  0 0.136
BIC =  -7.9

Compare this with the adequacy of just a general factor and no group factors
The degrees of freedom for just the general factor are 2  and the fit is  0.01 
The number of observations was  298  with Chi Square =  3.5  with prob <  0.17
The root mean square of the residuals is  0.02 
The df corrected root mean square of the residuals is  0.03 

RMSEA index =  0.05  and the 90 % confidence intervals are  0 0.136
BIC =  -7.9 

Measures of factor score adequacy             
                                                 g F1*
Correlation of scores with factors            0.94   0
Multiple R square of scores with factors      0.89   0
Minimum correlation of factor score estimates 0.77  -1

 Total, General and Subset omega for each subset
                                                 g  F1*
Omega total for total scores and subscales    0.87 0.87
Omega general for total scores and subscales  0.87 0.87
Omega group for total scores and subscales    0.00 0.00
omega_results$omega.tot    # Total Omega
[1] 0.8724752
omega_results$omega.h      # Hierarchical Omega
NULL
omega_results$omega.g      # Group Omega (if multiple factors)
        total   general group
g   0.8724752 0.8724835     0
F1* 0.8724835 0.8724835     0

6.3 Descriptives, correlation plot, EFA, CFA for “Perceived Bio-Inspiration Scale (PBS)”

6.3.1 Visual Resemblance to Nature (VRtN)

regEx <- "^Bioinspiration-VRtN"
nameVariable <- "VRtN"


sum(str_detect(string = colnames(dat), pattern = regEx))
[1] 4
tmp_dat <- na.omit(dat[,str_detect(string = colnames(dat), pattern = regEx)])


tmp <- CFAstats(dataset = tmp_dat, regularExp = regEx, labelLatent = str_remove(string = nameVariable, pattern = "mean_"), 
                showPlots = TRUE, 
                computeEFA = TRUE, 
                computeCFA = TRUE, 
                computeCFAMplus = FALSE)



descriptive statistics: 
                      Mean   SD Median CoeffofVariation Minimum Maximun
Bioinspiration-VRtN1  3.87 1.84      4             0.48       1       7
Bioinspiration-VRtN4r 4.97 1.75      5             0.35       1       7
Bioinspiration-VRtN2  5.14 1.48      5             0.29       1       7
Bioinspiration-VRtN3  5.39 1.34      6             0.25       1       7
                      Lower Quantile Upper Quantile Skewness Kurtosis(-3)
Bioinspiration-VRtN1               1              7    -0.14        -1.13
Bioinspiration-VRtN4r              1              7    -0.69        -0.50
Bioinspiration-VRtN2               1              7    -0.78         0.08
Bioinspiration-VRtN3               1              7    -0.89         0.55
                      KS-Test
Bioinspiration-VRtN1        0
Bioinspiration-VRtN4r       0
Bioinspiration-VRtN2        0
Bioinspiration-VRtN3        0


variables under investigation:  BioinspirationVRtN1 BioinspirationVRtN4r BioinspirationVRtN2 BioinspirationVRtN3 

Cronbachs Alpha: 0.77 

Parallel analysis suggests that the number of factors =  2  and the number of components =  1 
VRtN 
Number of components:  1 



EFA factor loadings (1 factor solution): 

Loadings:
                     MR1  
BioinspirationVRtN1  0.554
BioinspirationVRtN4r 0.751
BioinspirationVRtN2  0.815
BioinspirationVRtN3  0.771

                 MR1
SS loadings    2.129
Proportion Var 0.532
CFA summary and fit statistics: 
lavaan 0.6-19 ended normally after 24 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                         8

  Number of observations                           298

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                                22.720      21.166
  Degrees of freedom                                 2           2
  P-value (Chi-square)                           0.000       0.000
  Scaling correction factor                                  1.073
    Yuan-Bentler correction (Mplus variant)                       

Model Test Baseline Model:

  Test statistic                               336.565     219.325
  Degrees of freedom                                 6           6
  P-value                                        0.000       0.000
  Scaling correction factor                                  1.535

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    0.937       0.910
  Tucker-Lewis Index (TLI)                       0.812       0.730
                                                                  
  Robust Comparative Fit Index (CFI)                         0.937
  Robust Tucker-Lewis Index (TLI)                            0.811

Loglikelihood and Information Criteria:

  Loglikelihood user model (H0)              -2084.754   -2084.754
  Scaling correction factor                                  1.320
      for the MLR correction                                      
  Loglikelihood unrestricted model (H1)      -2073.394   -2073.394
  Scaling correction factor                                  1.271
      for the MLR correction                                      
                                                                  
  Akaike (AIC)                                4185.508    4185.508
  Bayesian (BIC)                              4215.085    4215.085
  Sample-size adjusted Bayesian (SABIC)       4189.714    4189.714

Root Mean Square Error of Approximation:

  RMSEA                                          0.186       0.179
  90 Percent confidence interval - lower         0.122       0.117
  90 Percent confidence interval - upper         0.259       0.249
  P-value H_0: RMSEA <= 0.050                    0.000       0.001
  P-value H_0: RMSEA >= 0.080                    0.996       0.995
                                                                  
  Robust RMSEA                                               0.186
  90 Percent confidence interval - lower                     0.120
  90 Percent confidence interval - upper                     0.261
  P-value H_0: Robust RMSEA <= 0.050                         0.001
  P-value H_0: Robust RMSEA >= 0.080                         0.995

Standardized Root Mean Square Residual:

  SRMR                                           0.050       0.050

Parameter Estimates:

  Standard errors                             Sandwich
  Information bread                           Observed
  Observed information based on                Hessian

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  VRtN =~                                                               
    BionsprtnVRtN1    1.000                               0.960    0.523
    BinsprtnVRtN4r    1.287    0.212    6.075    0.000    1.235    0.708
    BionsprtnVRtN2    1.147    0.129    8.907    0.000    1.101    0.745
    BionsprtnVRtN3    1.043    0.173    6.038    0.000    1.001    0.747

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .BionsprtnVRtN1    2.444    0.244   10.033    0.000    2.444    0.726
   .BinsprtnVRtN4r    1.518    0.269    5.635    0.000    1.518    0.499
   .BionsprtnVRtN2    0.974    0.205    4.754    0.000    0.974    0.445
   .BionsprtnVRtN3    0.794    0.125    6.342    0.000    0.794    0.442
    VRtN              0.921    0.225    4.100    0.000    1.000    1.000



CFA first 6 Modification Indices: 
                    lhs op                  rhs     mi    epc sepc.lv sepc.all
14 BioinspirationVRtN4r ~~  BioinspirationVRtN3 24.273  0.745   0.745    0.679
11  BioinspirationVRtN1 ~~  BioinspirationVRtN2 24.273  0.637   0.637    0.413
12  BioinspirationVRtN1 ~~  BioinspirationVRtN3  6.602 -0.301  -0.301   -0.216
13 BioinspirationVRtN4r ~~  BioinspirationVRtN2  6.602 -0.427  -0.427   -0.351
15  BioinspirationVRtN2 ~~  BioinspirationVRtN3  5.881 -0.337  -0.337   -0.383
10  BioinspirationVRtN1 ~~ BioinspirationVRtN4r  5.881 -0.362  -0.362   -0.188
   sepc.nox
14    0.679
11    0.413
12   -0.216
13   -0.351
15   -0.383
10   -0.188
des_tab <- tmp$desTable %>%
  as.data.frame() %>%
  select(Mean, SD, Skewness, `Kurtosis(-3)`, `KS-Test`)
stargazer(
  des_tab,
  summary = FALSE,
  rownames = TRUE,
  title = "Descriptive Statistics for Ecological Items",
  label = "tab:ecology_desc",
  digits = 2,
  table.placement = "ht!",
  font.size = "small"
)

% Table created by stargazer v.5.2.3 by Marek Hlavac, Social Policy Institute. E-mail: marek.hlavac at gmail.com
% Date and time: Do, Dez 18, 2025 - 11:02:35
\begin{table}[ht!] \centering 
  \caption{Descriptive Statistics for Ecological Items} 
  \label{tab:ecology_desc} 
\small 
\begin{tabular}{@{\extracolsep{5pt}} cccccc} 
\\[-1.8ex]\hline 
\hline \\[-1.8ex] 
 & Mean & SD & Skewness & Kurtosis(-3) & KS-Test \\ 
\hline \\[-1.8ex] 
Bioinspiration-VRtN1 & $3.87$ & $1.84$ & $$-$0.14$ & $$-$1.13$ & $0$ \\ 
Bioinspiration-VRtN4r & $4.97$ & $1.75$ & $$-$0.69$ & $$-$0.50$ & $0$ \\ 
Bioinspiration-VRtN2 & $5.14$ & $1.48$ & $$-$0.78$ & $0.08$ & $0$ \\ 
Bioinspiration-VRtN3 & $5.39$ & $1.34$ & $$-$0.89$ & $0.55$ & $0$ \\ 
\hline \\[-1.8ex] 
\end{tabular} 
\end{table} 
omega_results <- psych::omega(tmp_dat, nfactors = 1)  # or more if needed
omega_results
Omega 
Call: omegah(m = m, nfactors = nfactors, fm = fm, key = key, flip = flip, 
    digits = digits, title = title, sl = sl, labels = labels, 
    plot = plot, n.obs = n.obs, rotate = rotate, Phi = Phi, option = option, 
    covar = covar)
Alpha:                 0.77 
G.6:                   0.74 
Omega Hierarchical:    0.78 
Omega H asymptotic:    1 
Omega Total            0.78 

Schmid Leiman Factor loadings greater than  0.2 
                         g  F1*   h2   h2   u2 p2 com
Bioinspiration-VRtN1  0.52      0.27 0.27 0.73  1   1
Bioinspiration-VRtN4r 0.69      0.48 0.48 0.52  1   1
Bioinspiration-VRtN2  0.77      0.60 0.60 0.40  1   1
Bioinspiration-VRtN3  0.73      0.54 0.54 0.46  1   1

With Sums of squares  of:
   g  F1*   h2 
1.89 0.00 0.95 

general/max  1.98   max/min =   1.713853e+16
mean percent general =  1    with sd =  0 and cv of  0 
Explained Common Variance of the general factor =  1 

The degrees of freedom are 2  and the fit is  0.08 
The number of observations was  298  with Chi Square =  23.05  with prob <  9.9e-06
The root mean square of the residuals is  0.06 
The df corrected root mean square of the residuals is  0.11
RMSEA index =  0.188  and the 90 % confidence intervals are  0.124 0.261
BIC =  11.66

Compare this with the adequacy of just a general factor and no group factors
The degrees of freedom for just the general factor are 2  and the fit is  0.08 
The number of observations was  298  with Chi Square =  23.05  with prob <  9.9e-06
The root mean square of the residuals is  0.06 
The df corrected root mean square of the residuals is  0.11 

RMSEA index =  0.188  and the 90 % confidence intervals are  0.124 0.261
BIC =  11.66 

Measures of factor score adequacy             
                                                 g F1*
Correlation of scores with factors            0.89   0
Multiple R square of scores with factors      0.80   0
Minimum correlation of factor score estimates 0.60  -1

 Total, General and Subset omega for each subset
                                                 g  F1*
Omega total for total scores and subscales    0.78 0.78
Omega general for total scores and subscales  0.78 0.78
Omega group for total scores and subscales    0.00 0.00
omega_results$omega.tot    # Total Omega
[1] 0.7780778
omega_results$omega.h      # Hierarchical Omega
NULL
omega_results$omega.g      # Group Omega (if multiple factors)
        total   general        group
g   0.7780778 0.7785595 5.834108e-18
F1* 0.7785595 0.7785595 5.834108e-18

6.3.2 Intentionality & Perceived Inspiration (IPI)

regEx <- "^Bioinspiration-IPI"
nameVariable <- "IPI"


sum(str_detect(string = colnames(dat), pattern = regEx))
[1] 4
tmp_dat <- na.omit(dat[,str_detect(string = colnames(dat), pattern = regEx)])


tmp <- CFAstats(dataset = tmp_dat, regularExp = regEx, labelLatent = str_remove(string = nameVariable, pattern = "mean_"), 
                showPlots = TRUE, 
                computeEFA = TRUE, 
                computeCFA = TRUE, 
                computeCFAMplus = FALSE)



descriptive statistics: 
                     Mean   SD Median CoeffofVariation Minimum Maximun
Bioinspiration-IPI1  5.95 1.15      6             0.19       1       7
Bioinspiration-IPI2r 5.31 1.57      6             0.29       1       7
Bioinspiration-IPI3  5.91 1.14      6             0.19       2       7
Bioinspiration-IPI4  5.80 1.19      6             0.20       1       7
                     Lower Quantile Upper Quantile Skewness Kurtosis(-3)
Bioinspiration-IPI1               1              7    -1.10         1.04
Bioinspiration-IPI2r              1              7    -1.00         0.45
Bioinspiration-IPI3               2              7    -1.14         1.24
Bioinspiration-IPI4               1              7    -1.03         1.04
                     KS-Test
Bioinspiration-IPI1        0
Bioinspiration-IPI2r       0
Bioinspiration-IPI3        0
Bioinspiration-IPI4        0


variables under investigation:  BioinspirationIPI1 BioinspirationIPI2r BioinspirationIPI3 BioinspirationIPI4 

Cronbachs Alpha: 0.82 

Parallel analysis suggests that the number of factors =  1  and the number of components =  1 
IPI 
Number of components:  1 


EFA factor loadings (1 factor solution): 

Loadings:
                    MR1  
BioinspirationIPI1  0.920
BioinspirationIPI2r 0.576
BioinspirationIPI3  0.864
BioinspirationIPI4  0.847

                 MR1
SS loadings    2.642
Proportion Var 0.661
CFA summary and fit statistics: 
lavaan 0.6-19 ended normally after 19 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                         8

  Number of observations                           298

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                                 1.214       1.399
  Degrees of freedom                                 2           2
  P-value (Chi-square)                           0.545       0.497
  Scaling correction factor                                  0.867
    Yuan-Bentler correction (Mplus variant)                       

Model Test Baseline Model:

  Test statistic                               497.197     215.036
  Degrees of freedom                                 6           6
  P-value                                        0.000       0.000
  Scaling correction factor                                  2.312

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    1.000       1.000
  Tucker-Lewis Index (TLI)                       1.005       1.009
                                                                  
  Robust Comparative Fit Index (CFI)                         1.000
  Robust Tucker-Lewis Index (TLI)                            1.003

Loglikelihood and Information Criteria:

  Loglikelihood user model (H0)              -1707.055   -1707.055
  Scaling correction factor                                  2.253
      for the MLR correction                                      
  Loglikelihood unrestricted model (H1)      -1706.448   -1706.448
  Scaling correction factor                                  1.976
      for the MLR correction                                      
                                                                  
  Akaike (AIC)                                3430.109    3430.109
  Bayesian (BIC)                              3459.686    3459.686
  Sample-size adjusted Bayesian (SABIC)       3434.315    3434.315

Root Mean Square Error of Approximation:

  RMSEA                                          0.000       0.000
  90 Percent confidence interval - lower         0.000       0.000
  90 Percent confidence interval - upper         0.099       0.111
  P-value H_0: RMSEA <= 0.050                    0.737       0.672
  P-value H_0: RMSEA >= 0.080                    0.110       0.156
                                                                  
  Robust RMSEA                                               0.000
  90 Percent confidence interval - lower                     0.000
  90 Percent confidence interval - upper                     0.096
  P-value H_0: Robust RMSEA <= 0.050                         0.725
  P-value H_0: Robust RMSEA >= 0.080                         0.104

Standardized Root Mean Square Residual:

  SRMR                                           0.009       0.009

Parameter Estimates:

  Standard errors                             Sandwich
  Information bread                           Observed
  Observed information based on                Hessian

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  IPI =~                                                                
    BioinsprtnIPI1    1.000                               1.031    0.895
    BionsprtnIPI2r    0.672    0.099    6.806    0.000    0.692    0.443
    BioinsprtnIPI3    0.889    0.069   12.803    0.000    0.916    0.805
    BioinsprtnIPI4    0.899    0.074   12.074    0.000    0.926    0.783

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .BioinsprtnIPI1    0.264    0.059    4.490    0.000    0.264    0.199
   .BionsprtnIPI2r    1.962    0.279    7.023    0.000    1.962    0.804
   .BioinsprtnIPI3    0.455    0.085    5.350    0.000    0.455    0.351
   .BioinsprtnIPI4    0.543    0.133    4.068    0.000    0.543    0.387
    IPI               1.062    0.136    7.790    0.000    1.000    1.000



CFA first 6 Modification Indices: 
                   lhs op                 rhs    mi    epc sepc.lv sepc.all
10  BioinspirationIPI1 ~~ BioinspirationIPI2r 0.981 -0.066  -0.066   -0.092
15  BioinspirationIPI3 ~~  BioinspirationIPI4 0.981 -0.079  -0.079   -0.159
12  BioinspirationIPI1 ~~  BioinspirationIPI4 0.940  0.097   0.097    0.257
13 BioinspirationIPI2r ~~  BioinspirationIPI3 0.940  0.065   0.065    0.068
14 BioinspirationIPI2r ~~  BioinspirationIPI4 0.020  0.010   0.010    0.010
11  BioinspirationIPI1 ~~  BioinspirationIPI3 0.020  0.015   0.015    0.043
   sepc.nox
10   -0.092
15   -0.159
12    0.257
13    0.068
14    0.010
11    0.043
des_tab <- tmp$desTable %>%
  as.data.frame() %>%
  select(Mean, SD, Skewness, `Kurtosis(-3)`, `KS-Test`)
stargazer(
  des_tab,
  summary = FALSE,
  rownames = TRUE,
  title = "Descriptive Statistics for Ecological Items",
  label = "tab:ecology_desc",
  digits = 2,
  table.placement = "ht!",
  font.size = "small"
)

% Table created by stargazer v.5.2.3 by Marek Hlavac, Social Policy Institute. E-mail: marek.hlavac at gmail.com
% Date and time: Do, Dez 18, 2025 - 11:02:40
\begin{table}[ht!] \centering 
  \caption{Descriptive Statistics for Ecological Items} 
  \label{tab:ecology_desc} 
\small 
\begin{tabular}{@{\extracolsep{5pt}} cccccc} 
\\[-1.8ex]\hline 
\hline \\[-1.8ex] 
 & Mean & SD & Skewness & Kurtosis(-3) & KS-Test \\ 
\hline \\[-1.8ex] 
Bioinspiration-IPI1 & $5.95$ & $1.15$ & $$-$1.10$ & $1.04$ & $0$ \\ 
Bioinspiration-IPI2r & $5.31$ & $1.57$ & $$-$1$ & $0.45$ & $0$ \\ 
Bioinspiration-IPI3 & $5.91$ & $1.14$ & $$-$1.14$ & $1.24$ & $0$ \\ 
Bioinspiration-IPI4 & $5.80$ & $1.19$ & $$-$1.03$ & $1.04$ & $0$ \\ 
\hline \\[-1.8ex] 
\end{tabular} 
\end{table} 
omega_results <- psych::omega(tmp_dat, nfactors = 1)  # or more if needed
omega_results
Omega 
Call: omegah(m = m, nfactors = nfactors, fm = fm, key = key, flip = flip, 
    digits = digits, title = title, sl = sl, labels = labels, 
    plot = plot, n.obs = n.obs, rotate = rotate, Phi = Phi, option = option, 
    covar = covar)
Alpha:                 0.82 
G.6:                   0.8 
Omega Hierarchical:    0.83 
Omega H asymptotic:    1 
Omega Total            0.83 

Schmid Leiman Factor loadings greater than  0.2 
                        g  F1*   h2   h2   u2 p2 com
Bioinspiration-IPI1  0.89      0.79 0.79 0.21  1   1
Bioinspiration-IPI2r 0.45      0.20 0.20 0.80  1   1
Bioinspiration-IPI3  0.81      0.66 0.66 0.34  1   1
Bioinspiration-IPI4  0.78      0.61 0.61 0.39  1   1

With Sums of squares  of:
  g F1*  h2 
2.3 0.0 1.5 

general/max  1.54   max/min =   Inf
mean percent general =  1    with sd =  0 and cv of  0 
Explained Common Variance of the general factor =  1 

The degrees of freedom are 2  and the fit is  0 
The number of observations was  298  with Chi Square =  1.31  with prob <  0.52
The root mean square of the residuals is  0.01 
The df corrected root mean square of the residuals is  0.02
RMSEA index =  0  and the 90 % confidence intervals are  0 0.102
BIC =  -10.08

Compare this with the adequacy of just a general factor and no group factors
The degrees of freedom for just the general factor are 2  and the fit is  0 
The number of observations was  298  with Chi Square =  1.31  with prob <  0.52
The root mean square of the residuals is  0.01 
The df corrected root mean square of the residuals is  0.02 

RMSEA index =  0  and the 90 % confidence intervals are  0 0.102
BIC =  -10.08 

Measures of factor score adequacy             
                                                 g F1*
Correlation of scores with factors            0.94   0
Multiple R square of scores with factors      0.88   0
Minimum correlation of factor score estimates 0.76  -1

 Total, General and Subset omega for each subset
                                                 g  F1*
Omega total for total scores and subscales    0.83 0.83
Omega general for total scores and subscales  0.83 0.83
Omega group for total scores and subscales    0.00 0.00
omega_results$omega.tot    # Total Omega
[1] 0.8314019
omega_results$omega.h      # Hierarchical Omega
NULL
omega_results$omega.g      # Group Omega (if multiple factors)
        total   general group
g   0.8314019 0.8312676     0
F1* 0.8312676 0.8312676     0

6.3.3 Perceived Naturalness (PN)

regEx <- "^Bioinspiration-PN"
nameVariable <- "PN"


sum(str_detect(string = colnames(dat), pattern = regEx))
[1] 4
tmp_dat <- na.omit(dat[,str_detect(string = colnames(dat), pattern = regEx)])


tmp <- CFAstats(dataset = tmp_dat, regularExp = regEx, labelLatent = str_remove(string = nameVariable, pattern = "mean_"), 
                showPlots = TRUE, 
                computeEFA = TRUE, 
                computeCFA = TRUE, 
                computeCFAMplus = FALSE)



descriptive statistics: 
                    Mean   SD Median CoeffofVariation Minimum Maximun
Bioinspiration-PN4  3.96 1.72      4             0.43       1       7
Bioinspiration-PN2r 4.56 1.68      5             0.37       1       7
Bioinspiration-PN3  3.90 1.74      4             0.45       1       7
Bioinspiration-PN1  4.13 1.74      4             0.42       1       7
                    Lower Quantile Upper Quantile Skewness Kurtosis(-3) KS-Test
Bioinspiration-PN4               1              7    -0.13        -1.08       0
Bioinspiration-PN2r              1              7    -0.20        -1.05       0
Bioinspiration-PN3               1              7    -0.03        -1.04       0
Bioinspiration-PN1               1              7    -0.22        -1.02       0


variables under investigation:  BioinspirationPN4 BioinspirationPN2r BioinspirationPN3 BioinspirationPN1 
Some items ( Bioinspiration-PN2r ) were negatively correlated with the first principal component and 
probably should be reversed.  
To do this, run the function again with the 'check.keys=TRUE' optionCronbachs Alpha: 0.43 

Parallel analysis suggests that the number of factors =  2  and the number of components =  1 
PN 
Number of components:  1 



EFA factor loadings (1 factor solution): 

Loadings:
                   MR1   
BioinspirationPN4   0.732
BioinspirationPN2r -0.392
BioinspirationPN3   0.811
BioinspirationPN1   0.850

                 MR1
SS loadings    2.069
Proportion Var 0.517
CFA summary and fit statistics: 
lavaan 0.6-19 ended normally after 28 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                         8

  Number of observations                           298

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                                15.797      13.626
  Degrees of freedom                                 2           2
  P-value (Chi-square)                           0.000       0.001
  Scaling correction factor                                  1.159
    Yuan-Bentler correction (Mplus variant)                       

Model Test Baseline Model:

  Test statistic                               375.955     245.919
  Degrees of freedom                                 6           6
  P-value                                        0.000       0.000
  Scaling correction factor                                  1.529

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    0.963       0.952
  Tucker-Lewis Index (TLI)                       0.888       0.855
                                                                  
  Robust Comparative Fit Index (CFI)                         0.963
  Robust Tucker-Lewis Index (TLI)                            0.890

Loglikelihood and Information Criteria:

  Loglikelihood user model (H0)              -2155.339   -2155.339
  Scaling correction factor                                  1.095
      for the MLR correction                                      
  Loglikelihood unrestricted model (H1)      -2147.440   -2147.440
  Scaling correction factor                                  1.108
      for the MLR correction                                      
                                                                  
  Akaike (AIC)                                4326.678    4326.678
  Bayesian (BIC)                              4356.255    4356.255
  Sample-size adjusted Bayesian (SABIC)       4330.884    4330.884

Root Mean Square Error of Approximation:

  RMSEA                                          0.152       0.140
  90 Percent confidence interval - lower         0.088       0.080
  90 Percent confidence interval - upper         0.226       0.208
  P-value H_0: RMSEA <= 0.050                    0.006       0.009
  P-value H_0: RMSEA >= 0.080                    0.967       0.950
                                                                  
  Robust RMSEA                                               0.150
  90 Percent confidence interval - lower                     0.082
  90 Percent confidence interval - upper                     0.230
  P-value H_0: Robust RMSEA <= 0.050                         0.010
  P-value H_0: Robust RMSEA >= 0.080                         0.954

Standardized Root Mean Square Residual:

  SRMR                                           0.049       0.049

Parameter Estimates:

  Standard errors                             Sandwich
  Information bread                           Observed
  Observed information based on                Hessian

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  PN =~                                                                 
    BioinspirtnPN4    1.000                               1.124    0.654
    BioinsprtnPN2r   -0.484    0.098   -4.948    0.000   -0.544   -0.325
    BioinspirtnPN3    1.264    0.126   10.020    0.000    1.421    0.820
    BioinspirtnPN1    1.324    0.130   10.196    0.000    1.488    0.856

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .BioinspirtnPN4    1.692    0.198    8.558    0.000    1.692    0.572
   .BioinsprtnPN2r    2.514    0.173   14.563    0.000    2.514    0.895
   .BioinspirtnPN3    0.984    0.177    5.556    0.000    0.984    0.328
   .BioinspirtnPN1    0.808    0.183    4.405    0.000    0.808    0.267
    PN                1.263    0.221    5.718    0.000    1.000    1.000



CFA first 6 Modification Indices: 
                  lhs op                rhs     mi    epc sepc.lv sepc.all
15  BioinspirationPN3 ~~  BioinspirationPN1 15.365  1.771   1.771    1.986
10  BioinspirationPN4 ~~ BioinspirationPN2r 15.365 -0.512  -0.512   -0.249
11  BioinspirationPN4 ~~  BioinspirationPN3  4.338 -0.512  -0.512   -0.397
14 BioinspirationPN2r ~~  BioinspirationPN1  4.338  0.259   0.259    0.182
12  BioinspirationPN4 ~~  BioinspirationPN1  0.576 -0.201  -0.201   -0.172
13 BioinspirationPN2r ~~  BioinspirationPN3  0.576  0.093   0.093    0.059
   sepc.nox
15    1.986
10   -0.249
11   -0.397
14    0.182
12   -0.172
13    0.059

6.4 Delete Items

dat$`Bioinspiration-PN2r` <- NULL

6.4.1 run again: Perceived Naturalness (PN)

regEx <- "^Bioinspiration-PN"
nameVariable <- "PN"


sum(str_detect(string = colnames(dat), pattern = regEx))
[1] 3
tmp_dat <- na.omit(dat[,str_detect(string = colnames(dat), pattern = regEx)])


tmp <- CFAstats(dataset = tmp_dat, regularExp = regEx, labelLatent = str_remove(string = nameVariable, pattern = "mean_"), 
                showPlots = TRUE, 
                computeEFA = TRUE, 
                computeCFA = TRUE, 
                computeCFAMplus = FALSE)



descriptive statistics: 
                   Mean   SD Median CoeffofVariation Minimum Maximun
Bioinspiration-PN4 3.96 1.72      4             0.43       1       7
Bioinspiration-PN3 3.90 1.74      4             0.45       1       7
Bioinspiration-PN1 4.13 1.74      4             0.42       1       7
                   Lower Quantile Upper Quantile Skewness Kurtosis(-3) KS-Test
Bioinspiration-PN4              1              7    -0.13        -1.08       0
Bioinspiration-PN3              1              7    -0.03        -1.04       0
Bioinspiration-PN1              1              7    -0.22        -1.02       0


variables under investigation:  BioinspirationPN4 BioinspirationPN3 BioinspirationPN1 

Cronbachs Alpha: 0.82 

Parallel analysis suggests that the number of factors =  1  and the number of components =  1 
PN 
Number of components:  1 



EFA factor loadings (1 factor solution): 

Loadings:
                  MR1  
BioinspirationPN4 0.674
BioinspirationPN3 0.828
BioinspirationPN1 0.892

                 MR1
SS loadings    1.935
Proportion Var 0.645
CFA summary and fit statistics: 
lavaan 0.6-19 ended normally after 24 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                         6

  Number of observations                           298

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                                 0.000       0.000
  Degrees of freedom                                 0           0

Model Test Baseline Model:

  Test statistic                               332.640     182.283
  Degrees of freedom                                 3           3
  P-value                                        0.000       0.000
  Scaling correction factor                                  1.825

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    1.000       1.000
  Tucker-Lewis Index (TLI)                       1.000       1.000
                                                                  
  Robust Comparative Fit Index (CFI)                            NA
  Robust Tucker-Lewis Index (TLI)                               NA

Loglikelihood and Information Criteria:

  Loglikelihood user model (H0)              -1592.304   -1592.304
  Loglikelihood unrestricted model (H1)      -1592.304   -1592.304
                                                                  
  Akaike (AIC)                                3196.608    3196.608
  Bayesian (BIC)                              3218.790    3218.790
  Sample-size adjusted Bayesian (SABIC)       3199.762    3199.762

Root Mean Square Error of Approximation:

  RMSEA                                          0.000          NA
  90 Percent confidence interval - lower         0.000          NA
  90 Percent confidence interval - upper         0.000          NA
  P-value H_0: RMSEA <= 0.050                       NA          NA
  P-value H_0: RMSEA >= 0.080                       NA          NA
                                                                  
  Robust RMSEA                                               0.000
  90 Percent confidence interval - lower                     0.000
  90 Percent confidence interval - upper                     0.000
  P-value H_0: Robust RMSEA <= 0.050                            NA
  P-value H_0: Robust RMSEA >= 0.080                            NA

Standardized Root Mean Square Residual:

  SRMR                                           0.000       0.000

Parameter Estimates:

  Standard errors                             Sandwich
  Information bread                           Observed
  Observed information based on                Hessian

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  PN =~                                                                 
    BioinspirtnPN4    1.000                               1.097    0.638
    BioinspirtnPN3    1.288    0.125   10.303    0.000    1.413    0.815
    BioinspirtnPN1    1.379    0.141    9.784    0.000    1.513    0.870

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .BioinspirtnPN4    1.752    0.196    8.952    0.000    1.752    0.593
   .BioinspirtnPN3    1.006    0.186    5.413    0.000    1.006    0.335
   .BioinspirtnPN1    0.734    0.211    3.475    0.001    0.734    0.243
    PN                1.203    0.215    5.596    0.000    1.000    1.000



CFA first 6 Modification Indices: 
[1] lhs      op       rhs      mi       epc      sepc.lv  sepc.all sepc.nox
<0 Zeilen> (oder row.names mit Länge 0)
des_tab <- tmp$desTable %>%
  as.data.frame() %>%
  select(Mean, SD, Skewness, `Kurtosis(-3)`, `KS-Test`)
stargazer(
  des_tab,
  summary = FALSE,
  rownames = TRUE,
  title = "Descriptive Statistics for Ecological Items",
  label = "tab:ecology_desc",
  digits = 2,
  table.placement = "ht!",
  font.size = "small"
)

% Table created by stargazer v.5.2.3 by Marek Hlavac, Social Policy Institute. E-mail: marek.hlavac at gmail.com
% Date and time: Do, Dez 18, 2025 - 11:02:47
\begin{table}[ht!] \centering 
  \caption{Descriptive Statistics for Ecological Items} 
  \label{tab:ecology_desc} 
\small 
\begin{tabular}{@{\extracolsep{5pt}} cccccc} 
\\[-1.8ex]\hline 
\hline \\[-1.8ex] 
 & Mean & SD & Skewness & Kurtosis(-3) & KS-Test \\ 
\hline \\[-1.8ex] 
Bioinspiration-PN4 & $3.96$ & $1.72$ & $$-$0.13$ & $$-$1.08$ & $0$ \\ 
Bioinspiration-PN3 & $3.90$ & $1.74$ & $$-$0.03$ & $$-$1.04$ & $0$ \\ 
Bioinspiration-PN1 & $4.13$ & $1.74$ & $$-$0.22$ & $$-$1.02$ & $0$ \\ 
\hline \\[-1.8ex] 
\end{tabular} 
\end{table} 
omega_results <- psych::omega(tmp_dat, nfactors = 1)  # or more if needed
omega_results
Omega 
Call: omegah(m = m, nfactors = nfactors, fm = fm, key = key, flip = flip, 
    digits = digits, title = title, sl = sl, labels = labels, 
    plot = plot, n.obs = n.obs, rotate = rotate, Phi = Phi, option = option, 
    covar = covar)
Alpha:                 0.82 
G.6:                   0.76 
Omega Hierarchical:    0.82 
Omega H asymptotic:    1 
Omega Total            0.82 

Schmid Leiman Factor loadings greater than  0.2 
                      g  F1*   h2   h2   u2 p2 com
Bioinspiration-PN4 0.64      0.41 0.41 0.59  1   1
Bioinspiration-PN3 0.82      0.66 0.66 0.34  1   1
Bioinspiration-PN1 0.87      0.76 0.76 0.24  1   1

With Sums of squares  of:
  g F1*  h2 
1.8 0.0 1.2 

general/max  1.55   max/min =   Inf
mean percent general =  1    with sd =  0 and cv of  0 
Explained Common Variance of the general factor =  1 

The degrees of freedom are 0  and the fit is  0 
The number of observations was  298  with Chi Square =  0  with prob <  NA
The root mean square of the residuals is  0 
The df corrected root mean square of the residuals is  NA

Compare this with the adequacy of just a general factor and no group factors
The degrees of freedom for just the general factor are 0  and the fit is  0 
The number of observations was  298  with Chi Square =  0  with prob <  NA
The root mean square of the residuals is  0 
The df corrected root mean square of the residuals is  NA 

Measures of factor score adequacy             
                                                 g F1*
Correlation of scores with factors            0.92   0
Multiple R square of scores with factors      0.85   0
Minimum correlation of factor score estimates 0.71  -1

 Total, General and Subset omega for each subset
                                                 g  F1*
Omega total for total scores and subscales    0.82 0.82
Omega general for total scores and subscales  0.82 0.82
Omega group for total scores and subscales    0.00 0.00
omega_results$omega.tot    # Total Omega
[1] 0.8218047
omega_results$omega.h      # Hierarchical Omega
NULL
omega_results$omega.g      # Group Omega (if multiple factors)
        total   general group
g   0.8218047 0.8218035     0
F1* 0.8218035 0.8218035     0

6.4.2 run again: EFA for “Perceived Bio-Inspiration Scale (PBS)”

#### Overall EFA
regExOverall <- "^Bioinspiration"


psych::cor.plot(r = cor(dat[, str_detect(string = colnames(dat),
                                                   pattern = regExOverall)]
                        , use = "pairwise.complete.obs"),
                upper = FALSE, xlas = 2, main = "Overall")

#> parallel analysis
tmp_parallelAnalysis <- dimensionalityTest(label = "Overall",
                             regEx = regExOverall, dataset = dat)
Warning in fa.stats(r = r, f = f, phi = phi, n.obs = n.obs, np.obs = np.obs, :
The estimated weights for the factor scores are probably incorrect.  Try a
different factor score estimation method.

Parallel analysis suggests that the number of factors =  2  and the number of components =  2 
Overall 
Number of components:  2 
#> EFA (# of factors=5)
tmp_EFA <- explorativeFactorAnalysis(label = "Overall",
                                 regEx = regExOverall,
                                 dataset = dat, nfac = tmp_parallelAnalysis$nfact)
Warning in fa.stats(r = r, f = f, phi = phi, n.obs = n.obs, np.obs = np.obs, :
The estimated weights for the factor scores are probably incorrect.  Try a
different factor score estimation method.
tmp_EFA[[1]]
Factor Analysis using method =  minres
Call: fa(r = tmp_dat, nfactors = nfac, rotate = "promax", cor = "cor")
Standardized loadings (pattern matrix) based upon correlation matrix
                        MR1   MR2   h2   u2 com
Bioinspiration-VRtN1  -0.09  0.85 0.68 0.32 1.0
Bioinspiration-PN4    -0.02  0.67 0.44 0.56 1.0
Bioinspiration-VRtN4r  0.56  0.23 0.46 0.54 1.3
Bioinspiration-IPI1    0.89 -0.07 0.75 0.25 1.0
Bioinspiration-VRtN2   0.41  0.47 0.55 0.45 2.0
Bioinspiration-IPI2r   0.57 -0.27 0.28 0.72 1.4
Bioinspiration-PN3    -0.09  0.84 0.66 0.34 1.0
Bioinspiration-IPI3    0.79  0.01 0.63 0.37 1.0
Bioinspiration-IPI4    0.77  0.02 0.61 0.39 1.0
Bioinspiration-VRtN3   0.63  0.23 0.55 0.45 1.3
Bioinspiration-PN1     0.00  0.84 0.70 0.30 1.0

                       MR1  MR2
SS loadings           3.27 3.04
Proportion Var        0.30 0.28
Cumulative Var        0.30 0.57
Proportion Explained  0.52 0.48
Cumulative Proportion 0.52 1.00

 With factor correlations of 
     MR1  MR2
MR1 1.00 0.39
MR2 0.39 1.00

Mean item complexity =  1.2
Test of the hypothesis that 2 factors are sufficient.

df null model =  55  with the objective function =  5.75 with Chi Square =  1682.13
df of  the model are 34  and the objective function was  0.25 

The root mean square of the residuals (RMSR) is  0.03 
The df corrected root mean square of the residuals is  0.04 

The harmonic n.obs is  298 with the empirical chi square  30.34  with prob <  0.65 
The total n.obs was  298  with Likelihood Chi Square =  73.68  with prob <  9.4e-05 

Tucker Lewis Index of factoring reliability =  0.96
RMSEA index =  0.062  and the 90 % confidence intervals are  0.043 0.082
BIC =  -120.02
Fit based upon off diagonal values = 0.99
Measures of factor score adequacy             
                                                   MR1  MR2
Correlation of (regression) scores with factors   0.95 0.95
Multiple R square of scores with factors          0.90 0.90
Minimum correlation of possible factor scores     0.79 0.79

two factor structure, within bioinspiried dimensions no strong differences in overall answering patterns

6.5 evaluation videos

6.5.1 Subjective Outcome Evaluation Scale

regEx <- "^evalInf"
nameVariable <- "subOutEval"


sum(str_detect(string = colnames(dat), pattern = regEx))
[1] 10
tmp_dat <- na.omit(dat[,str_detect(string = colnames(dat), pattern = regEx)])


tmp <- CFAstats(dataset = tmp_dat, regularExp = regEx, labelLatent = str_remove(string = nameVariable, pattern = "mean_"), 
                showPlots = TRUE, 
                computeEFA = TRUE, 
                computeCFA = TRUE, 
                computeCFAMplus = FALSE)



descriptive statistics: 
           Mean   SD Median CoeffofVariation Minimum Maximun Lower Quantile
evalInf-6  4.94 0.99      5             0.20       1       6              1
evalInf-5  4.73 0.95      5             0.20       1       6              1
evalInf-8  4.82 0.98      5             0.20       1       6              1
evalInf-2  5.35 0.76      5             0.14       1       6              1
evalInf-3  4.86 1.12      5             0.23       1       6              1
evalInf-4  4.74 1.21      5             0.25       1       6              1
evalInf-10 4.83 1.09      5             0.23       1       6              1
evalInf-7  4.44 1.28      5             0.29       1       6              1
evalInf-1  4.62 1.16      5             0.25       1       6              1
evalInf-9  4.49 1.18      5             0.26       1       6              1
           Upper Quantile Skewness Kurtosis(-3) KS-Test
evalInf-6               6    -1.28         2.62       0
evalInf-5               6    -0.82         1.23       0
evalInf-8               6    -0.93         1.30       0
evalInf-2               6    -1.27         2.92       0
evalInf-3               6    -1.15         1.36       0
evalInf-4               6    -1.10         1.05       0
evalInf-10              6    -1.16         1.44       0
evalInf-7               6    -0.77         0.05       0
evalInf-1               6    -0.90         0.50       0
evalInf-9               6    -0.77         0.21       0


variables under investigation:  evalInf6 evalInf5 evalInf8 evalInf2 evalInf3 evalInf4 evalInf10 evalInf7 evalInf1 evalInf9 

Cronbachs Alpha: 0.94 

Parallel analysis suggests that the number of factors =  1  and the number of components =  1 
subOutEval 
Number of components:  1 


EFA factor loadings (1 factor solution): 

Loadings:
          MR1  
evalInf6  0.854
evalInf5  0.842
evalInf8  0.831
evalInf2  0.725
evalInf3  0.788
evalInf4  0.884
evalInf10 0.921
evalInf7  0.842
evalInf1  0.843
evalInf9  0.819

                 MR1
SS loadings    6.997
Proportion Var 0.700
CFA summary and fit statistics: 
lavaan 0.6-19 ended normally after 26 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                        20

  Number of observations                           298

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                               236.761     172.898
  Degrees of freedom                                35          35
  P-value (Chi-square)                           0.000       0.000
  Scaling correction factor                                  1.369
    Yuan-Bentler correction (Mplus variant)                       

Model Test Baseline Model:

  Test statistic                              2420.973    1646.477
  Degrees of freedom                                45          45
  P-value                                        0.000       0.000
  Scaling correction factor                                  1.470

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    0.915       0.914
  Tucker-Lewis Index (TLI)                       0.891       0.889
                                                                  
  Robust Comparative Fit Index (CFI)                         0.920
  Robust Tucker-Lewis Index (TLI)                            0.897

Loglikelihood and Information Criteria:

  Loglikelihood user model (H0)              -3310.953   -3310.953
  Scaling correction factor                                  1.729
      for the MLR correction                                      
  Loglikelihood unrestricted model (H1)      -3192.572   -3192.572
  Scaling correction factor                                  1.500
      for the MLR correction                                      
                                                                  
  Akaike (AIC)                                6661.906    6661.906
  Bayesian (BIC)                              6735.848    6735.848
  Sample-size adjusted Bayesian (SABIC)       6672.421    6672.421

Root Mean Square Error of Approximation:

  RMSEA                                          0.139       0.115
  90 Percent confidence interval - lower         0.123       0.101
  90 Percent confidence interval - upper         0.156       0.130
  P-value H_0: RMSEA <= 0.050                    0.000       0.000
  P-value H_0: RMSEA >= 0.080                    1.000       1.000
                                                                  
  Robust RMSEA                                               0.135
  90 Percent confidence interval - lower                     0.115
  90 Percent confidence interval - upper                     0.155
  P-value H_0: Robust RMSEA <= 0.050                         0.000
  P-value H_0: Robust RMSEA >= 0.080                         1.000

Standardized Root Mean Square Residual:

  SRMR                                           0.043       0.043

Parameter Estimates:

  Standard errors                             Sandwich
  Information bread                           Observed
  Observed information based on                Hessian

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  subOutEval =~                                                         
    evalInf6          1.000                               0.781    0.789
    evalInf5          0.968    0.069   14.097    0.000    0.756    0.794
    evalInf8          0.969    0.082   11.864    0.000    0.757    0.770
    evalInf2          0.585    0.050   11.613    0.000    0.457    0.602
    evalInf3          1.074    0.118    9.099    0.000    0.839    0.747
    evalInf4          1.331    0.108   12.282    0.000    1.040    0.864
    evalInf10         1.235    0.104   11.919    0.000    0.964    0.889
    evalInf7          1.325    0.093   14.183    0.000    1.035    0.811
    evalInf1          1.233    0.109   11.286    0.000    0.963    0.833
    evalInf9          1.211    0.092   13.146    0.000    0.946    0.800

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .evalInf6          0.370    0.042    8.761    0.000    0.370    0.378
   .evalInf5          0.336    0.031   10.757    0.000    0.336    0.370
   .evalInf8          0.393    0.045    8.778    0.000    0.393    0.407
   .evalInf2          0.367    0.068    5.380    0.000    0.367    0.638
   .evalInf3          0.556    0.067    8.337    0.000    0.556    0.441
   .evalInf4          0.367    0.047    7.886    0.000    0.367    0.254
   .evalInf10         0.248    0.033    7.563    0.000    0.248    0.210
   .evalInf7          0.558    0.068    8.197    0.000    0.558    0.343
   .evalInf1          0.410    0.043    9.611    0.000    0.410    0.307
   .evalInf9          0.503    0.074    6.790    0.000    0.503    0.360
    subOutEval        0.610    0.107    5.711    0.000    1.000    1.000



CFA first 6 Modification Indices: 
         lhs op       rhs     mi    epc sepc.lv sepc.all sepc.nox
62 evalInf10 ~~  evalInf1 57.841  0.176   0.176    0.551    0.551
53  evalInf3 ~~ evalInf10 30.424  0.141   0.141    0.379    0.379
61 evalInf10 ~~  evalInf7 27.677 -0.139  -0.139   -0.374   -0.374
58  evalInf4 ~~  evalInf7 21.550  0.144   0.144    0.318    0.318
65  evalInf7 ~~  evalInf9 16.289  0.140   0.140    0.264    0.264
54  evalInf3 ~~  evalInf7 15.866 -0.142  -0.142   -0.255   -0.255
des_tab <- tmp$desTable %>%
  as.data.frame() %>%
  select(Mean, SD, Skewness, `Kurtosis(-3)`, `KS-Test`)
stargazer(
  des_tab,
  summary = FALSE,
  rownames = TRUE,
  title = "Descriptive Statistics for Subjective Outcome Evaluation Items",
  label = "tab:ecology_desc",
  digits = 2,
  table.placement = "ht!",
  font.size = "small"
)

% Table created by stargazer v.5.2.3 by Marek Hlavac, Social Policy Institute. E-mail: marek.hlavac at gmail.com
% Date and time: Do, Dez 18, 2025 - 11:03:06
\begin{table}[ht!] \centering 
  \caption{Descriptive Statistics for Subjective Outcome Evaluation Items} 
  \label{tab:ecology_desc} 
\small 
\begin{tabular}{@{\extracolsep{5pt}} cccccc} 
\\[-1.8ex]\hline 
\hline \\[-1.8ex] 
 & Mean & SD & Skewness & Kurtosis(-3) & KS-Test \\ 
\hline \\[-1.8ex] 
evalInf-6 & $4.94$ & $0.99$ & $$-$1.28$ & $2.62$ & $0$ \\ 
evalInf-5 & $4.73$ & $0.95$ & $$-$0.82$ & $1.23$ & $0$ \\ 
evalInf-8 & $4.82$ & $0.98$ & $$-$0.93$ & $1.30$ & $0$ \\ 
evalInf-2 & $5.35$ & $0.76$ & $$-$1.27$ & $2.92$ & $0$ \\ 
evalInf-3 & $4.86$ & $1.12$ & $$-$1.15$ & $1.36$ & $0$ \\ 
evalInf-4 & $4.74$ & $1.21$ & $$-$1.10$ & $1.05$ & $0$ \\ 
evalInf-10 & $4.83$ & $1.09$ & $$-$1.16$ & $1.44$ & $0$ \\ 
evalInf-7 & $4.44$ & $1.28$ & $$-$0.77$ & $0.05$ & $0$ \\ 
evalInf-1 & $4.62$ & $1.16$ & $$-$0.90$ & $0.50$ & $0$ \\ 
evalInf-9 & $4.49$ & $1.18$ & $$-$0.77$ & $0.21$ & $0$ \\ 
\hline \\[-1.8ex] 
\end{tabular} 
\end{table} 
omega_results <- psych::omega(tmp_dat, nfactors = 1)  # or more if needed
omega_results
Omega 
Call: omegah(m = m, nfactors = nfactors, fm = fm, key = key, flip = flip, 
    digits = digits, title = title, sl = sl, labels = labels, 
    plot = plot, n.obs = n.obs, rotate = rotate, Phi = Phi, option = option, 
    covar = covar)
Alpha:                 0.94 
G.6:                   0.95 
Omega Hierarchical:    0.94 
Omega H asymptotic:    1 
Omega Total            0.94 

Schmid Leiman Factor loadings greater than  0.2 
              g  F1*   h2   h2   u2 p2 com
evalInf-6  0.80      0.64 0.64 0.36  1   1
evalInf-5  0.80      0.65 0.65 0.35  1   1
evalInf-8  0.78      0.61 0.61 0.39  1   1
evalInf-2  0.61      0.37 0.37 0.63  1   1
evalInf-3  0.74      0.55 0.55 0.45  1   1
evalInf-4  0.86      0.74 0.74 0.26  1   1
evalInf-10 0.88      0.78 0.78 0.22  1   1
evalInf-7  0.81      0.66 0.66 0.34  1   1
evalInf-1  0.82      0.67 0.67 0.33  1   1
evalInf-9  0.80      0.63 0.63 0.37  1   1

With Sums of squares  of:
  g F1*  h2 
6.3 0.0 4.1 

general/max  1.54   max/min =   7.350603e+16
mean percent general =  1    with sd =  0 and cv of  0 
Explained Common Variance of the general factor =  1 

The degrees of freedom are 35  and the fit is  0.8 
The number of observations was  298  with Chi Square =  233.99  with prob <  2.8e-31
The root mean square of the residuals is  0.05 
The df corrected root mean square of the residuals is  0.05
RMSEA index =  0.138  and the 90 % confidence intervals are  0.122 0.155
BIC =  34.59

Compare this with the adequacy of just a general factor and no group factors
The degrees of freedom for just the general factor are 35  and the fit is  0.8 
The number of observations was  298  with Chi Square =  233.99  with prob <  2.8e-31
The root mean square of the residuals is  0.05 
The df corrected root mean square of the residuals is  0.05 

RMSEA index =  0.138  and the 90 % confidence intervals are  0.122 0.155
BIC =  34.59 

Measures of factor score adequacy             
                                                 g F1*
Correlation of scores with factors            0.98   0
Multiple R square of scores with factors      0.95   0
Minimum correlation of factor score estimates 0.90  -1

 Total, General and Subset omega for each subset
                                                 g  F1*
Omega total for total scores and subscales    0.94 0.94
Omega general for total scores and subscales  0.94 0.94
Omega group for total scores and subscales    0.00 0.00
omega_results$omega.tot    # Total Omega
[1] 0.9440978
omega_results$omega.h      # Hierarchical Omega
NULL
omega_results$omega.g      # Group Omega (if multiple factors)
        total   general        group
g   0.9440978 0.9440534 8.386201e-19
F1* 0.9440534 0.9440534 8.386201e-19

6.5.2 Situational Interest Scale - Design

regEx <- "Design$"
nameVariable <- "sitIntScale_Design"


sum(str_detect(string = colnames(dat), pattern = regEx))
[1] 6
tmp_dat <- na.omit(dat[,str_detect(string = colnames(dat), pattern = regEx)])


tmp <- CFAstats(dataset = tmp_dat, regularExp = regEx, labelLatent = str_remove(string = nameVariable, pattern = "mean_"), 
                showPlots = TRUE, 
                computeEFA = TRUE, 
                computeCFA = TRUE, 
                computeCFAMplus = FALSE)



descriptive statistics: 
                   Mean   SD Median CoeffofVariation Minimum Maximun
excitingDesign     4.00 1.68      4             0.42       1       7
entertainingDesign 4.44 1.66      5             0.37       1       7
boringDesign       5.02 1.75      5             0.35       1       7
usefulDesign       5.38 1.30      6             0.24       1       7
unnecessaryDesign  5.90 1.30      6             0.22       1       7
unimportantDesign  5.84 1.31      6             0.23       1       7
                   Lower Quantile Upper Quantile Skewness Kurtosis(-3) KS-Test
excitingDesign                  1              7    -0.05        -0.82       0
entertainingDesign              1              7    -0.31        -0.75       0
boringDesign                    1              7    -0.69        -0.46       0
usefulDesign                    1              7    -0.91         0.80       0
unnecessaryDesign               1              7    -1.26         1.24       0
unimportantDesign               1              7    -1.15         0.90       0


variables under investigation:  excitingDesign entertainingDesign boringDesign usefulDesign unnecessaryDesign unimportantDesign 

Cronbachs Alpha: 0.87 

Parallel analysis suggests that the number of factors =  3  and the number of components =  1 
sitIntScale_Design 
Number of components:  1 



EFA factor loadings (1 factor solution): 

Loadings:
                   MR1  
excitingDesign     0.758
entertainingDesign 0.818
boringDesign       0.829
usefulDesign       0.689
unnecessaryDesign  0.781
unimportantDesign  0.771

                 MR1
SS loadings    3.609
Proportion Var 0.602
CFA summary and fit statistics: 
lavaan 0.6-19 ended normally after 23 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                        12

  Number of observations                           298

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                               311.660     173.881
  Degrees of freedom                                 9           9
  P-value (Chi-square)                           0.000       0.000
  Scaling correction factor                                  1.792
    Yuan-Bentler correction (Mplus variant)                       

Model Test Baseline Model:

  Test statistic                              1098.414     538.845
  Degrees of freedom                                15          15
  P-value                                        0.000       0.000
  Scaling correction factor                                  2.038

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    0.721       0.685
  Tucker-Lewis Index (TLI)                       0.534       0.475
                                                                  
  Robust Comparative Fit Index (CFI)                         0.723
  Robust Tucker-Lewis Index (TLI)                            0.539

Loglikelihood and Information Criteria:

  Loglikelihood user model (H0)              -2849.324   -2849.324
  Scaling correction factor                                  1.742
      for the MLR correction                                      
  Loglikelihood unrestricted model (H1)      -2693.494   -2693.494
  Scaling correction factor                                  1.764
      for the MLR correction                                      
                                                                  
  Akaike (AIC)                                5722.647    5722.647
  Bayesian (BIC)                              5767.012    5767.012
  Sample-size adjusted Bayesian (SABIC)       5728.956    5728.956

Root Mean Square Error of Approximation:

  RMSEA                                          0.336       0.248
  90 Percent confidence interval - lower         0.304       0.224
  90 Percent confidence interval - upper         0.368       0.272
  P-value H_0: RMSEA <= 0.050                    0.000       0.000
  P-value H_0: RMSEA >= 0.080                    1.000       1.000
                                                                  
  Robust RMSEA                                               0.332
  90 Percent confidence interval - lower                     0.290
  90 Percent confidence interval - upper                     0.376
  P-value H_0: Robust RMSEA <= 0.050                         0.000
  P-value H_0: Robust RMSEA >= 0.080                         1.000

Standardized Root Mean Square Residual:

  SRMR                                           0.125       0.125

Parameter Estimates:

  Standard errors                             Sandwich
  Information bread                           Observed
  Observed information based on                Hessian

Latent Variables:
                        Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  sitIntScale_Design =~                                                      
    excitingDesign         1.000                               1.389    0.830
    entertanngDsgn         1.050    0.040   25.959    0.000    1.458    0.880
    boringDesign           0.996    0.086   11.612    0.000    1.384    0.794
    usefulDesign           0.555    0.071    7.761    0.000    0.771    0.594
    unnecessryDsgn         0.542    0.098    5.553    0.000    0.753    0.580
    unimportntDsgn         0.563    0.096    5.840    0.000    0.782    0.596

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .excitingDesign    0.872    0.171    5.094    0.000    0.872    0.311
   .entertanngDsgn    0.617    0.166    3.705    0.000    0.617    0.225
   .boringDesign      1.122    0.232    4.841    0.000    1.122    0.369
   .usefulDesign      1.091    0.146    7.483    0.000    1.091    0.648
   .unnecessryDsgn    1.117    0.178    6.291    0.000    1.117    0.663
   .unimportntDsgn    1.110    0.183    6.063    0.000    1.110    0.645
    sitIntScl_Dsgn    1.930    0.241    8.024    0.000    1.000    1.000



CFA first 6 Modification Indices: 
                  lhs op                rhs      mi    epc sepc.lv sepc.all
28  unnecessaryDesign ~~  unimportantDesign 165.022  0.888   0.888    0.797
14     excitingDesign ~~ entertainingDesign 102.910  0.958   0.958    1.306
17     excitingDesign ~~  unnecessaryDesign  43.094 -0.467  -0.467   -0.473
18     excitingDesign ~~  unimportantDesign  39.251 -0.447  -0.447   -0.455
21 entertainingDesign ~~  unnecessaryDesign  37.256 -0.415  -0.415   -0.501
26       usefulDesign ~~  unnecessaryDesign  27.797  0.361   0.361    0.327
   sepc.nox
28    0.797
14    1.306
17   -0.473
18   -0.455
21   -0.501
26    0.327
des_tab <- tmp$desTable %>%
  as.data.frame() %>%
  select(Mean, SD, Skewness, `Kurtosis(-3)`, `KS-Test`)
stargazer(
  des_tab,
  summary = FALSE,
  rownames = TRUE,
  title = "Descriptive Statistics for Situational Interest Design Items",
  label = "tab:ecology_desc",
  digits = 2,
  table.placement = "ht!",
  font.size = "small"
)

% Table created by stargazer v.5.2.3 by Marek Hlavac, Social Policy Institute. E-mail: marek.hlavac at gmail.com
% Date and time: Do, Dez 18, 2025 - 11:03:15
\begin{table}[ht!] \centering 
  \caption{Descriptive Statistics for Situational Interest Design Items} 
  \label{tab:ecology_desc} 
\small 
\begin{tabular}{@{\extracolsep{5pt}} cccccc} 
\\[-1.8ex]\hline 
\hline \\[-1.8ex] 
 & Mean & SD & Skewness & Kurtosis(-3) & KS-Test \\ 
\hline \\[-1.8ex] 
excitingDesign & $4$ & $1.68$ & $$-$0.05$ & $$-$0.82$ & $0$ \\ 
entertainingDesign & $4.44$ & $1.66$ & $$-$0.31$ & $$-$0.75$ & $0$ \\ 
boringDesign & $5.02$ & $1.75$ & $$-$0.69$ & $$-$0.46$ & $0$ \\ 
usefulDesign & $5.38$ & $1.30$ & $$-$0.91$ & $0.80$ & $0$ \\ 
unnecessaryDesign & $5.90$ & $1.30$ & $$-$1.26$ & $1.24$ & $0$ \\ 
unimportantDesign & $5.84$ & $1.31$ & $$-$1.15$ & $0.90$ & $0$ \\ 
\hline \\[-1.8ex] 
\end{tabular} 
\end{table} 
omega_results <- psych::omega(tmp_dat, nfactors = 1)  # or more if needed
omega_results
Omega 
Call: omegah(m = m, nfactors = nfactors, fm = fm, key = key, flip = flip, 
    digits = digits, title = title, sl = sl, labels = labels, 
    plot = plot, n.obs = n.obs, rotate = rotate, Phi = Phi, option = option, 
    covar = covar)
Alpha:                 0.87 
G.6:                   0.9 
Omega Hierarchical:    0.87 
Omega H asymptotic:    1 
Omega Total            0.87 

Schmid Leiman Factor loadings greater than  0.2 
                      g  F1*   h2   h2   u2 p2 com
excitingDesign     0.74      0.54 0.54 0.46  1   1
entertainingDesign 0.81      0.65 0.65 0.35  1   1
boringDesign       0.79      0.63 0.63 0.37  1   1
usefulDesign       0.63      0.40 0.40 0.60  1   1
unnecessaryDesign  0.70      0.49 0.49 0.51  1   1
unimportantDesign  0.71      0.50 0.50 0.50  1   1

With Sums of squares  of:
  g F1*  h2 
3.2 0.0 1.8 

general/max  1.82   max/min =   Inf
mean percent general =  1    with sd =  0 and cv of  0 
Explained Common Variance of the general factor =  1 

The degrees of freedom are 9  and the fit is  1.1 
The number of observations was  298  with Chi Square =  323.15  with prob <  3.2e-64
The root mean square of the residuals is  0.13 
The df corrected root mean square of the residuals is  0.17
RMSEA index =  0.342  and the 90 % confidence intervals are  0.311 0.375
BIC =  271.88

Compare this with the adequacy of just a general factor and no group factors
The degrees of freedom for just the general factor are 9  and the fit is  1.1 
The number of observations was  298  with Chi Square =  323.15  with prob <  3.2e-64
The root mean square of the residuals is  0.13 
The df corrected root mean square of the residuals is  0.17 

RMSEA index =  0.342  and the 90 % confidence intervals are  0.311 0.375
BIC =  271.88 

Measures of factor score adequacy             
                                                 g F1*
Correlation of scores with factors            0.94   0
Multiple R square of scores with factors      0.88   0
Minimum correlation of factor score estimates 0.76  -1

 Total, General and Subset omega for each subset
                                                 g  F1*
Omega total for total scores and subscales    0.87 0.87
Omega general for total scores and subscales  0.87 0.87
Omega group for total scores and subscales    0.00 0.00
omega_results$omega.tot    # Total Omega
[1] 0.8726258
omega_results$omega.h      # Hierarchical Omega
NULL
omega_results$omega.g      # Group Omega (if multiple factors)
        total   general group
g   0.8726258 0.8722623     0
F1* 0.8722623 0.8722623     0

6.5.3 Situational Interest Scale - Topic

regEx <- "Topic$"
nameVariable <- "sitIntScale_Topic"


sum(str_detect(string = colnames(dat), pattern = regEx))
[1] 6
tmp_dat <- na.omit(dat[,str_detect(string = colnames(dat), pattern = regEx)])


tmp <- CFAstats(dataset = tmp_dat, regularExp = regEx, labelLatent = str_remove(string = nameVariable, pattern = "mean_"), 
                showPlots = TRUE, 
                computeEFA = TRUE, 
                computeCFA = TRUE, 
                computeCFAMplus = FALSE)



descriptive statistics: 
                  Mean   SD Median CoeffofVariation Minimum Maximun
excitingTopic     4.73 1.68      5             0.36       1       7
entertainingTopic 4.73 1.60      5             0.34       1       7
boringTopic       5.56 1.70      6             0.31       1       7
usefulTopic       5.18 1.43      5             0.28       1       7
unnecessaryTopic  5.94 1.34      6             0.23       1       7
unimportantTopic  5.98 1.30      6             0.22       1       7
                  Lower Quantile Upper Quantile Skewness Kurtosis(-3) KS-Test
excitingTopic                  1              7    -0.57        -0.48       0
entertainingTopic              1              7    -0.58        -0.30       0
boringTopic                    1              7    -1.13         0.24       0
usefulTopic                    1              7    -0.83         0.55       0
unnecessaryTopic               1              7    -1.48         2.03       0
unimportantTopic               1              7    -1.35         1.51       0


variables under investigation:  excitingTopic entertainingTopic boringTopic usefulTopic unnecessaryTopic unimportantTopic 

Cronbachs Alpha: 0.91 

Parallel analysis suggests that the number of factors =  2  and the number of components =  1 
sitIntScale_Topic 
Number of components:  1 


EFA factor loadings (1 factor solution): 

Loadings:
                  MR1  
excitingTopic     0.825
entertainingTopic 0.823
boringTopic       0.900
usefulTopic       0.695
unnecessaryTopic  0.862
unimportantTopic  0.874

                 MR1
SS loadings    4.158
Proportion Var 0.693
CFA summary and fit statistics: 
lavaan 0.6-19 ended normally after 32 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                        12

  Number of observations                           298

Model Test User Model:
                                              Standard      Scaled
  Test Statistic                               429.130     413.324
  Degrees of freedom                                 9           9
  P-value (Chi-square)                           0.000       0.000
  Scaling correction factor                                  1.038
    Yuan-Bentler correction (Mplus variant)                       

Model Test Baseline Model:

  Test statistic                              1511.962     651.470
  Degrees of freedom                                15          15
  P-value                                        0.000       0.000
  Scaling correction factor                                  2.321

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    0.719       0.365
  Tucker-Lewis Index (TLI)                       0.532      -0.059
                                                                  
  Robust Comparative Fit Index (CFI)                         0.716
  Robust Tucker-Lewis Index (TLI)                            0.526

Loglikelihood and Information Criteria:

  Loglikelihood user model (H0)              -2718.166   -2718.166
  Scaling correction factor                                  2.771
      for the MLR correction                                      
  Loglikelihood unrestricted model (H1)      -2503.601   -2503.601
  Scaling correction factor                                  2.028
      for the MLR correction                                      
                                                                  
  Akaike (AIC)                                5460.331    5460.331
  Bayesian (BIC)                              5504.697    5504.697
  Sample-size adjusted Bayesian (SABIC)       5466.640    5466.640

Root Mean Square Error of Approximation:

  RMSEA                                          0.396       0.388
  90 Percent confidence interval - lower         0.364       0.357
  90 Percent confidence interval - upper         0.428       0.420
  P-value H_0: RMSEA <= 0.050                    0.000       0.000
  P-value H_0: RMSEA >= 0.080                    1.000       1.000
                                                                  
  Robust RMSEA                                               0.396
  90 Percent confidence interval - lower                     0.364
  90 Percent confidence interval - upper                     0.429
  P-value H_0: Robust RMSEA <= 0.050                         0.000
  P-value H_0: Robust RMSEA >= 0.080                         1.000

Standardized Root Mean Square Residual:

  SRMR                                           0.143       0.143

Parameter Estimates:

  Standard errors                             Sandwich
  Information bread                           Observed
  Observed information based on                Hessian

Latent Variables:
                       Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  sitIntScale_Topic =~                                                      
    excitingTopic         1.000                               1.032    0.614
    entertainngTpc        0.962    0.043   22.600    0.000    0.993    0.621
    boringTopic           1.238    0.103   11.976    0.000    1.278    0.754
    usefulTopic           0.804    0.080   10.054    0.000    0.829    0.581
    unnecessaryTpc        1.218    0.158    7.707    0.000    1.257    0.936
    unimportantTpc        1.196    0.152    7.865    0.000    1.234    0.952

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .excitingTopic     1.757    0.229    7.690    0.000    1.757    0.623
   .entertainngTpc    1.572    0.202    7.774    0.000    1.572    0.615
   .boringTopic       1.238    0.205    6.029    0.000    1.238    0.431
   .usefulTopic       1.346    0.196    6.861    0.000    1.346    0.662
   .unnecessaryTpc    0.222    0.105    2.124    0.034    0.222    0.123
   .unimportantTpc    0.159    0.072    2.218    0.027    0.159    0.094
    sitIntScal_Tpc    1.065    0.243    4.383    0.000    1.000    1.000



CFA first 6 Modification Indices: 
                 lhs op               rhs      mi    epc sepc.lv sepc.all
28  unnecessaryTopic ~~  unimportantTopic 349.451  1.061   1.061    5.648
14     excitingTopic ~~ entertainingTopic 178.389  1.331   1.331    0.801
19 entertainingTopic ~~       boringTopic  91.210  0.817   0.817    0.586
15     excitingTopic ~~       boringTopic  79.384  0.805   0.805    0.546
17     excitingTopic ~~  unnecessaryTopic  41.941 -0.325  -0.325   -0.520
22 entertainingTopic ~~  unimportantTopic  37.150 -0.278  -0.278   -0.557
   sepc.nox
28    5.648
14    0.801
19    0.586
15    0.546
17   -0.520
22   -0.557
des_tab <- tmp$desTable %>%
  as.data.frame() %>%
  select(Mean, SD, Skewness, `Kurtosis(-3)`, `KS-Test`)
stargazer(
  des_tab,
  summary = FALSE,
  rownames = TRUE,
  title = "Descriptive Statistics for Situational Interest Topic Items",
  label = "tab:ecology_desc",
  digits = 2,
  table.placement = "ht!",
  font.size = "small"
)

% Table created by stargazer v.5.2.3 by Marek Hlavac, Social Policy Institute. E-mail: marek.hlavac at gmail.com
% Date and time: Do, Dez 18, 2025 - 11:03:25
\begin{table}[ht!] \centering 
  \caption{Descriptive Statistics for Situational Interest Topic Items} 
  \label{tab:ecology_desc} 
\small 
\begin{tabular}{@{\extracolsep{5pt}} cccccc} 
\\[-1.8ex]\hline 
\hline \\[-1.8ex] 
 & Mean & SD & Skewness & Kurtosis(-3) & KS-Test \\ 
\hline \\[-1.8ex] 
excitingTopic & $4.73$ & $1.68$ & $$-$0.57$ & $$-$0.48$ & $0$ \\ 
entertainingTopic & $4.73$ & $1.60$ & $$-$0.58$ & $$-$0.30$ & $0$ \\ 
boringTopic & $5.56$ & $1.70$ & $$-$1.13$ & $0.24$ & $0$ \\ 
usefulTopic & $5.18$ & $1.43$ & $$-$0.83$ & $0.55$ & $0$ \\ 
unnecessaryTopic & $5.94$ & $1.34$ & $$-$1.48$ & $2.03$ & $0$ \\ 
unimportantTopic & $5.98$ & $1.30$ & $$-$1.35$ & $1.51$ & $0$ \\ 
\hline \\[-1.8ex] 
\end{tabular} 
\end{table} 
omega_results <- psych::omega(tmp_dat, nfactors = 1)  # or more if needed
omega_results
Omega 
Call: omegah(m = m, nfactors = nfactors, fm = fm, key = key, flip = flip, 
    digits = digits, title = title, sl = sl, labels = labels, 
    plot = plot, n.obs = n.obs, rotate = rotate, Phi = Phi, option = option, 
    covar = covar)
Alpha:                 0.91 
G.6:                   0.93 
Omega Hierarchical:    0.91 
Omega H asymptotic:    1 
Omega Total            0.91 

Schmid Leiman Factor loadings greater than  0.2 
                     g  F1*   h2   h2   u2 p2 com
excitingTopic     0.80      0.64 0.64 0.36  1   1
entertainingTopic 0.80      0.65 0.65 0.35  1   1
boringTopic       0.85      0.73 0.73 0.27  1   1
usefulTopic       0.63      0.40 0.40 0.60  1   1
unnecessaryTopic  0.80      0.64 0.64 0.36  1   1
unimportantTopic  0.82      0.68 0.68 0.32  1   1

With Sums of squares  of:
  g F1*  h2 
3.7 0.0 2.4 

general/max  1.56   max/min =   Inf
mean percent general =  1    with sd =  0 and cv of  0 
Explained Common Variance of the general factor =  1 

The degrees of freedom are 9  and the fit is  1.51 
The number of observations was  298  with Chi Square =  443.59  with prob <  6.7e-90
The root mean square of the residuals is  0.11 
The df corrected root mean square of the residuals is  0.14
RMSEA index =  0.403  and the 90 % confidence intervals are  0.372 0.436
BIC =  392.32

Compare this with the adequacy of just a general factor and no group factors
The degrees of freedom for just the general factor are 9  and the fit is  1.51 
The number of observations was  298  with Chi Square =  443.59  with prob <  6.7e-90
The root mean square of the residuals is  0.11 
The df corrected root mean square of the residuals is  0.14 

RMSEA index =  0.403  and the 90 % confidence intervals are  0.372 0.436
BIC =  392.32 

Measures of factor score adequacy             
                                                 g F1*
Correlation of scores with factors            0.96   0
Multiple R square of scores with factors      0.92   0
Minimum correlation of factor score estimates 0.83  -1

 Total, General and Subset omega for each subset
                                                 g  F1*
Omega total for total scores and subscales    0.91 0.91
Omega general for total scores and subscales  0.91 0.91
Omega group for total scores and subscales    0.00 0.00
omega_results$omega.tot    # Total Omega
[1] 0.9072878
omega_results$omega.h      # Hierarchical Omega
NULL
omega_results$omega.g      # Group Omega (if multiple factors)
        total   general group
g   0.9072878 0.9072105     0
F1* 0.9072105 0.9072105     0

6.6 Item Response Theory (polytomous) for “Perceived Bio-Inspiration Scale (PBS)”

Factor Loadings (F1) indicate how strongly each item is associated with the latent trait, rule of thumb:

  • 0.70 = strong
  • 0.40–0.69 = moderate
  • < 0.40 = weak

Communality (h²) is the proportion of variance in each item explained by the factor, rule of thumb: + h² > 0.40 → item is well represented + h² < 0.30 → potentially problematic item

if(runIRTmodels){
  # Choose dataset and regular expression
  regEx <- "^Bioinspiration"
  
  # Filter variables matching the pattern
  irt_items <- dat[, str_detect(colnames(dat), pattern = regEx)]
  
  # Drop rows with missing data (mirt requires complete cases)
  irt_items <- na.omit(irt_items)
  
  # Ensure all items are treated as ordered factors
  irt_items[] <- lapply(irt_items, function(x) as.numeric(as.character(x)))
  # Fit Graded Response Model (1-factor)
  mod_grm <- mirt(data = irt_items, model = 1, itemtype = "graded", verbose = FALSE)
  
  # Summarize model
  summary(mod_grm)
  
  
  # Plot Item Characteristic Curves (ICCs) for all items
  plot(mod_grm, type = "trace", facet_items = TRUE, main = "Item Characteristic Curves")
  
  # Plot Test Information Curve
  plot(mod_grm, type = "info", main = "Test Information Curve: Bioinspiration")
  
  
  
  ### compare results to:
  cor.plot(r = cor(irt_items))
}

Compare 1-Factor vs. 2-Factor Models:

if(runIRTmodels){
  mod_1f <- mirt(data = irt_items, model = 1, itemtype = "graded", verbose = FALSE)
  mod_2f <- mirt(data = irt_items, model = 2, itemtype = "graded", verbose = FALSE)
  mod_3f <- mirt(data = irt_items, model = 3, itemtype = "graded", verbose = FALSE)
  anova(mod_1f, mod_2f, mod_3f)
  
  summary(mod_2f)
summary(mod_3f)
}

significant p-value (e.g., < .05) supports the X-factor model.

7 Compute mean scores

dat$mean_Bioinspiration <- rowMeans(x = dat[,str_subset(colnames(dat), pattern = "^Bioinspiration")])
dat$mean_Bioinspiration_PN <- rowMeans(x = dat[,str_subset(colnames(dat), pattern = "^Bioinspiration-PN")])
dat$mean_Bioinspiration_IPI <- rowMeans(x = dat[,str_subset(colnames(dat), pattern = "^Bioinspiration-IPI")])
dat$mean_Bioinspiration_VRtN <- rowMeans(x = dat[,str_subset(colnames(dat), pattern = "^Bioinspiration-VRtN")])

dat$mean_Ecological <- rowMeans(x = dat[,str_subset(colnames(dat), pattern = "^EcologicalDimension")])

dat$mean_GAToRS_pp <- rowMeans(x = dat[,str_subset(colnames(dat), pattern = "^GAToRS.*pp$")])
dat$mean_GAToRS_pn <- rowMeans(x = dat[,str_subset(colnames(dat), pattern = "^GAToRS.*pn$")])
dat$mean_GAToRS_sp <- rowMeans(x = dat[,str_subset(colnames(dat), pattern = "^GAToRS.*sp$")])
dat$mean_GAToRS_sn <- rowMeans(x = dat[,str_subset(colnames(dat), pattern = "^GAToRS.*sn$")])


dat$mean_video_evalInf <- rowMeans(x = dat[,str_subset(colnames(dat), pattern = "^evalInf")])
dat$mean_video_sitintTopic <- rowMeans(x = dat[,str_subset(colnames(dat), pattern = "Topic$")])
dat$mean_video_sitintDesign <- rowMeans(x = dat[,str_subset(colnames(dat), pattern = "Design$")])

7.1 manifest correlations:

psych::cor.plot(r = cor(dat[, str_detect(string = colnames(dat),
                                                   pattern = "^mean_")]
                        , use = "pairwise.complete.obs"),
                upper = FALSE, xlas = 2, main = "Overall")

psych::cor.plot(r = cor(dat[dat$framingCondition == "bio-inspired", str_detect(string = colnames(dat),
                                                   pattern = "^mean_")]
                        , use = "pairwise.complete.obs"),
                upper = FALSE, xlas = 2, main = "For subset bio-inspired")

plot(dat[dat$framingCondition == "bio-inspired", "mean_Ecological"], dat[dat$framingCondition == "bio-inspired", "mean_Bioinspiration_IPI"]) # PN most strongly related to sustainability

cor(dat[dat$framingCondition == "bio-inspired", "mean_Ecological"], dat[dat$framingCondition == "bio-inspired", "mean_Bioinspiration_PN"])
[1] 0.4648864
psych::cor.plot(r = cor(dat[dat$framingCondition == "tech-inspired", str_detect(string = colnames(dat),
                                                   pattern = "^mean_")]
                        , use = "pairwise.complete.obs"),
                upper = FALSE, xlas = 2, main = "For subset tech-inspired")

7.2 descriptive:

dat %>% 
  group_by(framingCondition) %>%
  dplyr::summarise(
    N = n(),
    mean_Eco = mean(mean_Ecological, na.rm = TRUE),
    sd_Eco   = sd(mean_Ecological, na.rm = TRUE),
    
    mean_BioOverall = mean(mean_Bioinspiration, na.rm = TRUE),
    sd_BioOverall   = sd(mean_Bioinspiration, na.rm = TRUE),
    
    mean_Bio_PN = mean(mean_Bioinspiration_PN, na.rm = TRUE),
    sd_Bio_PN   = sd(mean_Bioinspiration_PN, na.rm = TRUE),
    
    mean_Bio_IPI = mean(mean_Bioinspiration_IPI, na.rm = TRUE),
    sd_Bio_IPI   = sd(mean_Bioinspiration_IPI, na.rm = TRUE),
    
    mean_Bio_VRtN = mean(mean_Bioinspiration_VRtN, na.rm = TRUE),
    sd_Bio_VRtN   = sd(mean_Bioinspiration_VRtN, na.rm = TRUE)
  )
# A tibble: 2 × 12
  framingCondition     N mean_Eco sd_Eco mean_BioOverall sd_BioOverall
  <fct>            <int>    <dbl>  <dbl>           <dbl>         <dbl>
1 bio-inspired       160     5.62   1.05            5.02         0.937
2 tech-inspired      138     5.53   1.09            4.85         1.04 
# ℹ 6 more variables: mean_Bio_PN <dbl>, sd_Bio_PN <dbl>, mean_Bio_IPI <dbl>,
#   sd_Bio_IPI <dbl>, mean_Bio_VRtN <dbl>, sd_Bio_VRtN <dbl>
psych::describe(x = dat[, c("mean_video_evalInf", "mean_video_sitintTopic", "mean_video_sitintDesign")])
                        vars   n mean   sd median trimmed  mad min max range
mean_video_evalInf         1 298 4.78 0.88   5.00    4.86 0.74 1.3   6   4.7
mean_video_sitintTopic     2 298 5.35 1.25   5.67    5.47 1.24 1.0   7   6.0
mean_video_sitintDesign    3 298 5.09 1.18   5.17    5.15 1.24 1.0   7   6.0
                         skew kurtosis   se
mean_video_evalInf      -0.93     0.87 0.05
mean_video_sitintTopic  -0.89     0.50 0.07
mean_video_sitintDesign -0.46    -0.32 0.07
hist(dat$mean_video_evalInf)

hist(dat$mean_video_sitintTopic)

hist(dat$mean_video_sitintDesign)

psych::cor.plot(r = cor(dat[, c("mean_video_evalInf", "mean_video_sitintTopic", "mean_video_sitintDesign")]
                        , use = "pairwise.complete.obs"),
                upper = FALSE, xlas = 2, main = "Overall")

8 Test Hypotheses

8.1 Descriptive

# Summaries of participant-level scores by framing condition
eco_summary <- data_summary(dat, "mean_Ecological", "framingCondition")
Lade nötiges Paket: plyr
------------------------------------------------------------------------------
You have loaded plyr after dplyr - this is likely to cause problems.
If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
library(plyr); library(dplyr)
------------------------------------------------------------------------------

Attache Paket: 'plyr'
Die folgenden Objekte sind maskiert von 'package:dplyr':

    arrange, count, desc, failwith, id, mutate, rename, summarise,
    summarize
Das folgende Objekt ist maskiert 'package:purrr':

    compact
bio_summary <- data_summary(dat, "mean_Bioinspiration", "framingCondition")

# View results
print(eco_summary)
  framingCondition mean_Ecological         se
1     bio-inspired        5.623437 0.08264248
2    tech-inspired        5.528986 0.09246271
print(bio_summary)
  framingCondition mean_Bioinspiration         se
1     bio-inspired            5.019886 0.07408534
2    tech-inspired            4.845850 0.08876130
# Plots the mean scores on the Bioinspiration & Ecological Dimension by Framing Condition
ggplot(dat, aes(x = framingCondition, y = mean_Ecological)) +
  geom_boxplot(fill = "lightgreen") +
  labs(title = "Ecological Dimension by Framing", y = "Mean Score") +
  theme_minimal()

ggplot(dat, aes(x = framingCondition, y = mean_Bioinspiration)) +
  geom_boxplot(fill = "skyblue") +
  labs(title = "Bioinspiration by Framing", y = "Mean Score") +
  theme_minimal()

8.2 ANOVAs

ANOVAs + post hoc tests:

8.2.1 for Perceived Ecological Sustainability Scale (PES)

# --- ANOVA for Ecological Dimension - PN ---
aov_out <- aov_ez(
  id = "PROLIFIC_PID",  # replace with your participant ID column name
  dv = "mean_Ecological",
  data = dat,
  between = "framingCondition"
)
print(aov_out)
Anova Table (Type 3 tests)

Response: mean_Ecological
            Effect     df  MSE    F  ges p.value
1 framingCondition 1, 296 1.13 0.58 .002    .446
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1
# Post hoc (Tukey) for Ecological
em_eco <- emmeans(aov_out, "framingCondition")
eco_posthoc <- pairs(em_eco, adjust = "tukey")
print(eco_posthoc)
 contrast                         estimate    SE  df t.ratio p.value
 (bio-inspired) - (tech-inspired)   0.0945 0.124 296   0.764  0.4456
# Summarize means and SE for plotting
plot_data <- data_summary(dat, "mean_Ecological", "framingCondition")

# --- Plot ---
ggplot(plot_data, aes(x = framingCondition, y = mean_Ecological)) +
  geom_col(fill = "grey80", color = "black", width = 0.6) +
  geom_errorbar(aes(ymin = mean_Ecological - se, ymax = mean_Ecological + se), width = 0.15) +
  labs(x = "Framing Condition", y = "Mean PES Score") +
  theme_apa() +
  theme(
    axis.title = element_text(face = "bold"),
    legend.position = "none"
  )

8.2.2 for Perceived Bio-Inspiration Scale (PBS) - overall

# --- ANOVA for Ecological Dimension - PN ---
aov_out <- aov_ez(
  id = "PROLIFIC_PID",  # replace with your participant ID column name
  dv = "mean_Bioinspiration",
  data = dat,
  between = "framingCondition"
)
print(aov_out)
Anova Table (Type 3 tests)

Response: mean_Bioinspiration
            Effect     df  MSE    F  ges p.value
1 framingCondition 1, 296 0.97 2.30 .008    .130
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1
# Post hoc (Tukey) for Ecological
em_eco <- emmeans(aov_out, "framingCondition")
eco_posthoc <- pairs(em_eco, adjust = "tukey")
print(eco_posthoc)
 contrast                         estimate    SE  df t.ratio p.value
 (bio-inspired) - (tech-inspired)    0.174 0.115 296   1.517  0.1303
# Summarize means and SE for plotting
plot_data <- data_summary(dat, "mean_Bioinspiration", "framingCondition")

# --- Plot ---
ggplot(plot_data, aes(x = framingCondition, y = mean_Bioinspiration)) +
  geom_col(fill = "grey80", color = "black", width = 0.6) +
  geom_errorbar(aes(ymin = mean_Bioinspiration - se, ymax = mean_Bioinspiration + se), width = 0.15) +
  labs(x = "Framing Condition", y = "Mean PBS Score") +
  theme_apa() +
  theme(
    axis.title = element_text(face = "bold"),
    legend.position = "none"
  )

8.2.3 for PBS - Perceived Naturalness (PN)

# --- ANOVA for Ecological Dimension - PN ---
aov_out <- aov_ez(
  id = "PROLIFIC_PID",  # replace with your participant ID column name
  dv = "mean_Bioinspiration_PN",
  data = dat,
  between = "framingCondition"
)
print(aov_out)
Anova Table (Type 3 tests)

Response: mean_Bioinspiration_PN
            Effect     df  MSE    F  ges p.value
1 framingCondition 1, 296 2.18 2.27 .008    .133
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1
# Post hoc (Tukey) for Ecological
em_eco <- emmeans(aov_out, "framingCondition")
eco_posthoc <- pairs(em_eco, adjust = "tukey")
print(eco_posthoc)
 contrast                         estimate    SE  df t.ratio p.value
 (bio-inspired) - (tech-inspired)   -0.259 0.172 296  -1.506  0.1332
# Summarize means and SE for plotting
plot_data <- data_summary(dat, "mean_Bioinspiration_PN", "framingCondition")

# --- Plot ---
ggplot(plot_data, aes(x = framingCondition, y = mean_Bioinspiration_PN)) +
  geom_col(fill = "grey80", color = "black", width = 0.6) +
  geom_errorbar(aes(ymin = mean_Bioinspiration_PN - se, ymax = mean_Bioinspiration_PN + se), width = 0.15) +
  labs(x = "Framing Condition", y = "Mean PN Score") +
  theme_apa() +
  theme(
    axis.title = element_text(face = "bold"),
    legend.position = "none"
  )

8.2.4 for PBS - Intentionality & Perceived Inspiration (IPI)

# --- ANOVA for Ecological Dimension - PN ---
aov_out <- aov_ez(
  id = "PROLIFIC_PID",  # replace with your participant ID column name
  dv = "mean_Bioinspiration_IPI",
  data = dat,
  between = "framingCondition"
)
print(aov_out)
Anova Table (Type 3 tests)

Response: mean_Bioinspiration_IPI
            Effect     df  MSE         F  ges p.value
1 framingCondition 1, 296 0.93 25.36 *** .079   <.001
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1
# Post hoc (Tukey) for Ecological
em_eco <- emmeans(aov_out, "framingCondition")
eco_posthoc <- pairs(em_eco, adjust = "tukey")
print(eco_posthoc)
 contrast                         estimate    SE  df t.ratio p.value
 (bio-inspired) - (tech-inspired)    0.563 0.112 296   5.036  <.0001
# Summarize means and SE for plotting
plot_data <- data_summary(dat, "mean_Bioinspiration_IPI", "framingCondition")

# --- Plot ---
ggplot(plot_data, aes(x = framingCondition, y = mean_Bioinspiration_IPI)) +
  geom_col(fill = "grey80", color = "black", width = 0.6) +
  geom_errorbar(aes(ymin = mean_Bioinspiration_IPI - se, ymax = mean_Bioinspiration_IPI + se), width = 0.15) +
  labs(x = "Framing Condition", y = "Mean IPI Score") +
  theme_apa() +
  theme(
    axis.title = element_text(face = "bold"),
    legend.position = "none"
  )

8.2.5 for PBS - Visual Resemblance to Nature (VRtN)

# --- ANOVA for Ecological Dimension - PN ---
aov_out <- aov_ez(
  id = "PROLIFIC_PID",  # replace with your participant ID column name
  dv = "mean_Bioinspiration_VRtN",
  data = dat,
  between = "framingCondition"
)
print(aov_out)
Anova Table (Type 3 tests)

Response: mean_Bioinspiration_VRtN
            Effect     df  MSE    F  ges p.value
1 framingCondition 1, 296 1.51 0.59 .002    .444
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1
# Post hoc (Tukey) for Ecological
em_eco <- emmeans(aov_out, "framingCondition")
eco_posthoc <- pairs(em_eco, adjust = "tukey")
print(eco_posthoc)
 contrast                         estimate    SE  df t.ratio p.value
 (bio-inspired) - (tech-inspired)     0.11 0.143 296   0.766  0.4441
# Summarize means and SE for plotting
plot_data <- data_summary(dat, "mean_Bioinspiration_VRtN", "framingCondition")

# --- Plot ---
ggplot(plot_data, aes(x = framingCondition, y = mean_Bioinspiration_VRtN)) +
  geom_col(fill = "grey80", color = "black", width = 0.6) +
  geom_errorbar(aes(ymin = mean_Bioinspiration_VRtN - se, ymax = mean_Bioinspiration_VRtN + se), width = 0.15) +
  labs(x = "Framing Condition", y = "Mean VRtN Score") +
  theme_apa() +
  theme(
    axis.title = element_text(face = "bold"),
    legend.position = "none"
  )

8.3 Spillover

We are comparing the effect size or magnitude of:

  • How much “bioinspired” framing boosts sustainability ratings.
  • How much “sustainable” framing boosts bioinspiration ratings.
# Subset only relevant cases and variables
dat_subset <- dat %>%
  # filter(framingCondition %in% c("bioinspired", "sustainable")) %>%
  select(PROLIFIC_PID, framingCondition, mean_Bioinspiration, mean_Ecological)


# Convert to long format (NO z-scores)
dat_long <- dat_subset %>%
  pivot_longer(
    cols = c(mean_Bioinspiration, mean_Ecological),
    names_to = "ratingType",
    values_to = "ratingScore"
  ) %>%
  mutate(
    ratingType = dplyr::recode(
      ratingType,
      "mean_Bioinspiration" = "Bioinspiration",
      "mean_Ecological"     = "Sustainability"
    ),
    framingCondition = factor(framingCondition),
    ratingType = factor(ratingType)
  )

dat_long$ratingType <- as.factor(dat_long$ratingType)

The interaction term now reflects difference in effect sizes in standard deviation units (comparable spillover strength):

levels(dat_long$framingCondition)
[1] "bio-inspired"  "tech-inspired"
levels(dat_long$ratingType)
[1] "Bioinspiration" "Sustainability"
# Run interaction model
model_lm <- lm(ratingScore ~ framingCondition * ratingType, data = dat_long)
summary(model_lm)

Call:
lm(formula = ratingScore ~ framingCondition * ratingType, data = dat_long)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.2790 -0.6563  0.1266  0.7210  2.1542 

Coefficients:
                                                       Estimate Std. Error
(Intercept)                                             5.01989    0.08116
framingConditiontech-inspired                          -0.17404    0.11927
ratingTypeSustainability                                0.60355    0.11478
framingConditiontech-inspired:ratingTypeSustainability  0.07958    0.16867
                                                       t value Pr(>|t|)    
(Intercept)                                             61.849  < 2e-16 ***
framingConditiontech-inspired                           -1.459    0.145    
ratingTypeSustainability                                 5.258 2.03e-07 ***
framingConditiontech-inspired:ratingTypeSustainability   0.472    0.637    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.027 on 592 degrees of freedom
Multiple R-squared:  0.09304,   Adjusted R-squared:  0.08845 
F-statistic: 20.24 on 3 and 592 DF,  p-value: 1.68e-12
stargazer(model_lm)

% Table created by stargazer v.5.2.3 by Marek Hlavac, Social Policy Institute. E-mail: marek.hlavac at gmail.com
% Date and time: Do, Dez 18, 2025 - 11:03:30
\begin{table}[!htbp] \centering 
  \caption{} 
  \label{} 
\begin{tabular}{@{\extracolsep{5pt}}lc} 
\\[-1.8ex]\hline 
\hline \\[-1.8ex] 
 & \multicolumn{1}{c}{\textit{Dependent variable:}} \\ 
\cline{2-2} 
\\[-1.8ex] & ratingScore \\ 
\hline \\[-1.8ex] 
 framingConditiontech-inspired & $-$0.174 \\ 
  & (0.119) \\ 
  & \\ 
 ratingTypeSustainability & 0.604$^{***}$ \\ 
  & (0.115) \\ 
  & \\ 
 framingConditiontech-inspired:ratingTypeSustainability & 0.080 \\ 
  & (0.169) \\ 
  & \\ 
 Constant & 5.020$^{***}$ \\ 
  & (0.081) \\ 
  & \\ 
\hline \\[-1.8ex] 
Observations & 596 \\ 
R$^{2}$ & 0.093 \\ 
Adjusted R$^{2}$ & 0.088 \\ 
Residual Std. Error & 1.027 (df = 592) \\ 
F Statistic & 20.245$^{***}$ (df = 3; 592) \\ 
\hline 
\hline \\[-1.8ex] 
\textit{Note:}  & \multicolumn{1}{r}{$^{*}$p$<$0.1; $^{**}$p$<$0.05; $^{***}$p$<$0.01} \\ 
\end{tabular} 
\end{table} 

no differences in mean scores between groups, only changes in variance:

library(lme4)
library(lmerTest)

Attache Paket: 'lmerTest'
Das folgende Objekt ist maskiert 'package:lme4':

    lmer
Das folgende Objekt ist maskiert 'package:stats':

    step
library(performance)


model_mixed <- lmer(
  ratingScore ~ framingCondition * ratingType +
    (1 | PROLIFIC_PID),
  data = dat_long
)

icc(model_mixed)
# Intraclass Correlation Coefficient

    Adjusted ICC: 0.444
  Unadjusted ICC: 0.403
summary(model_mixed)
Linear mixed model fit by REML. t-tests use Satterthwaite's method [
lmerModLmerTest]
Formula: ratingScore ~ framingCondition * ratingType + (1 | PROLIFIC_PID)
   Data: dat_long

REML criterion at convergence: 1666.2

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-3.0657 -0.5057  0.1117  0.5749  1.9990 

Random effects:
 Groups       Name        Variance Std.Dev.
 PROLIFIC_PID (Intercept) 0.4679   0.6840  
 Residual                 0.5861   0.7656  
Number of obs: 596, groups:  PROLIFIC_PID, 298

Fixed effects:
                                                        Estimate Std. Error
(Intercept)                                              5.01989    0.08116
framingConditiontech-inspired                           -0.17404    0.11927
ratingTypeSustainability                                 0.60355    0.08559
framingConditiontech-inspired:ratingTypeSustainability   0.07958    0.12578
                                                              df t value
(Intercept)                                            494.54184  61.849
framingConditiontech-inspired                          494.54184  -1.459
ratingTypeSustainability                               296.00001   7.051
framingConditiontech-inspired:ratingTypeSustainability 296.00001   0.633
                                                       Pr(>|t|)    
(Intercept)                                             < 2e-16 ***
framingConditiontech-inspired                             0.145    
ratingTypeSustainability                               1.25e-11 ***
framingConditiontech-inspired:ratingTypeSustainability    0.527    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Correlation of Fixed Effects:
            (Intr) frmnC- rtngTS
frmngCndtn- -0.681              
rtngTypSstn -0.527  0.359       
frmngCn-:TS  0.359 -0.527 -0.681
dat_long %>%
  group_by(framingCondition, ratingType) %>%
  dplyr::summarise(
    N = n(),
    mean_DV = mean(ratingScore, na.rm = TRUE)
  )
`summarise()` has grouped output by 'framingCondition'. You can override using
the `.groups` argument.
# A tibble: 4 × 4
# Groups:   framingCondition [2]
  framingCondition ratingType         N mean_DV
  <fct>            <fct>          <int>   <dbl>
1 bio-inspired     Bioinspiration   160    5.02
2 bio-inspired     Sustainability   160    5.62
3 tech-inspired    Bioinspiration   138    4.85
4 tech-inspired    Sustainability   138    5.53
ggplot(dat_long, aes(x = framingCondition, y = ratingScore, fill = ratingType)) +
    scale_fill_manual(
    values = c("Bioinspiration" = "#A67C49", "Sustainability" = "#55A868")
  ) +
  stat_summary(fun = mean, geom = "bar", position = position_dodge(0.7), width = 0.6, color = "black") +
  stat_summary(fun.data = mean_se, geom = "errorbar", 
               position = position_dodge(0.7), width = 0.15) +
  labs(x = "Framing Condition", y = "Rating Score", fill = "Rating Type") +
  theme_minimal()

ggplot(dat_long, aes(x = ratingType, y = ratingScore, fill = framingCondition)) +
    scale_fill_manual(
    values = c("tech-inspired" = "#A67C49", "bio-inspired" = "#55A868")
  ) +
  stat_summary(fun = mean, geom = "bar", position = position_dodge(0.7), width = 0.6, color = "black") +
  stat_summary(fun.data = mean_se, geom = "errorbar", 
               position = position_dodge(0.7), width = 0.15) +
  labs(x = "Rating Type", y = "Rating Score", fill = "Framing Condition") +
  theme_minimal()

# Estimated marginal means for each cell
emm <- emmeans(model_lm, ~ framingCondition * ratingType)
emm
 framingCondition ratingType     emmean     SE  df lower.CL upper.CL
 bio-inspired     Bioinspiration   5.02 0.0812 592     4.86     5.18
 tech-inspired    Bioinspiration   4.85 0.0874 592     4.67     5.02
 bio-inspired     Sustainability   5.62 0.0812 592     5.46     5.78
 tech-inspired    Sustainability   5.53 0.0874 592     5.36     5.70

Confidence level used: 0.95 
# Simple effects of ratingType within each level of framingCondition
simple_rating_by_frame <- contrast(
  emm,
  method = "pairwise",
  by = "framingCondition",
  adjust = "none"   # or "bonferroni", "holm", etc. if you like
)

summary(simple_rating_by_frame)
framingCondition = bio-inspired:
 contrast                        estimate    SE  df t.ratio p.value
 Bioinspiration - Sustainability   -0.604 0.115 592  -5.258  <.0001

framingCondition = tech-inspired:
 contrast                        estimate    SE  df t.ratio p.value
 Bioinspiration - Sustainability   -0.683 0.124 592  -5.527  <.0001
# Simple effects of framingCondition within each level of ratingType
simple_frame_by_rating <- contrast(
  emm,
  method = "pairwise",
  by = "ratingType",
  adjust = "none"
)

summary(simple_frame_by_rating)
ratingType = Bioinspiration:
 contrast                         estimate    SE  df t.ratio p.value
 (bio-inspired) - (tech-inspired)   0.1740 0.119 592   1.459  0.1450

ratingType = Sustainability:
 contrast                         estimate    SE  df t.ratio p.value
 (bio-inspired) - (tech-inspired)   0.0945 0.119 592   0.792  0.4287
all_contrasts <- contrast(emm, method = "pairwise", adjust = "none")
summary(all_contrasts)
 contrast                                                        estimate    SE
 (bio-inspired Bioinspiration) - (tech-inspired Bioinspiration)    0.1740 0.119
 (bio-inspired Bioinspiration) - (bio-inspired Sustainability)    -0.6036 0.115
 (bio-inspired Bioinspiration) - (tech-inspired Sustainability)   -0.5091 0.119
 (tech-inspired Bioinspiration) - (bio-inspired Sustainability)   -0.7776 0.119
 (tech-inspired Bioinspiration) - (tech-inspired Sustainability)  -0.6831 0.124
 (bio-inspired Sustainability) - (tech-inspired Sustainability)    0.0945 0.119
  df t.ratio p.value
 592   1.459  0.1450
 592  -5.258  <.0001
 592  -4.268  <.0001
 592  -6.520  <.0001
 592  -5.527  <.0001
 592   0.792  0.4287
plot(emm, comparisons = TRUE, by = "framingCondition")

plot(emm, comparisons = TRUE, by = "ratingType")

9 Heterogeneity

9.1 latent class analysis for mean items

manifest correlations:

psych::cor.plot(r = cor(dat[, str_detect(string = colnames(dat),
                                                   pattern = "^mean_")]
                        , use = "pairwise.complete.obs"),
                upper = FALSE, xlas = 2, main = "Overall")

hist(dat$mean_Bioinspiration)

hist(dat$mean_Bioinspiration_PN)

hist(dat$mean_Bioinspiration_IPI)

hist(dat$mean_Bioinspiration_VRtN)

hist(dat$mean_Ecological)

length(unique(dat$ID))
[1] 298
length(unique(dat$PROLIFIC_PID))
[1] 298
setwd("outputs/LCA_means")


if(runMplusLCA){
  

  LCA_dat <- dat[, c("ID", "mean_Ecological", "mean_Bioinspiration_PN", "mean_Bioinspiration_IPI", "mean_Bioinspiration_VRtN")]
  

  tmp <- str_subset(string = colnames(LCA_dat), pattern = "^mean_")
  tmp <- str_remove_all(string = tmp, pattern = "^mean_")
    tmp <- str_remove_all(string = tmp, pattern = "inspiration|logical")

  # cat(paste0(tmp, "(", 1:length(tmp), ")"))
  # cat(paste0(tmp))


  colnames(LCA_dat) <- c("ID", tmp)


  # prepareMplusData(df = LCA_dat, filename = "LCA_dat.dat")


  l = 1
  list_lca_means <- list()
  for(i in 2:LCArunsDef){
    print(i)

    numClasses <- i

    LCA_mplus  <- mplusObject(

      TITLE = paste0("Latent Class Analysis Mean Scales", " c=", numClasses),

      VARIABLE =paste0("
  usevariables = Eco Bio_PN Bio_IPI Bio_VRtN;

  classes      = c(", numClasses, ")"),

  ANALYSIS =
    "
    Type=mixture; ! LCA analysis
    STARTS= 500 100;
    !LRTstarts=0 0 300 20;
  ",

  PLOT =
    "
    type = plot3;
    series is Eco(1) Bio_PN(2) Bio_IPI(3) Bio_VRtN(4);
  ",

  SAVEDATA = paste0("file = lca_", numClasses, ".txt ;
    save = cprob;
    format = free;
  "),

  OUTPUT = "tech11 tech14;", rdata = LCA_dat)

    list_lca_means[[l]] <- mplusModeler(LCA_mplus,
                                         modelout = paste0("lca_means", numClasses, ".inp"),
                                         run = 1L)

    l = l + 1
  }

  # comment out to avoid overwriting LCA outputs
  saveRDS(list_lca_means, file="list_lca_means.rds")

}else{
  list_lca_means <- readRDS("list_lca_means.rds" )
}
getLCAfitstatistics(listMplusOutput = list_lca_means)

  Classes        LL      AIC      BIC    SABIC     CAIC BLRTp VLMRLRTp Entropy
1       2 -1769.348 3564.696 3612.759 3571.531 3625.758  0.00   0.0000   0.749
2       3 -1731.445 3498.890 3565.437 3508.353 3583.438  0.00   0.0155   0.766
3       4 -1706.929 3459.858 3544.892 3471.950 3567.891  0.00   0.2417   0.764
4       5 -1684.834 3425.668 3529.187 3440.389 3557.187  0.00   0.0316   0.783
5       6 -1666.555 3399.110 3521.114 3416.459 3554.114  0.00   0.1797   0.787
6       7 -1655.183 3386.367 3526.856 3406.344 3564.856  0.00   0.3161   0.798
7       8 -1644.944 3375.887 3534.862 3398.493 3577.863  0.02   0.2400   0.813
### number of classes
num_classes <- 3 # index - 1

# Step 1: Extract means
params <- list_lca_means[[num_classes]]$results$parameters$unstandardized

means_df <- params %>%
  filter(paramHeader == "Means" & !grepl("^C#\\d$", param))

# Step 2: Get class proportions
class_counts <- table(list_lca_means[[num_classes]]$results$savedata$C)
total_n <- sum(class_counts)
class_props <- round(100 * class_counts / total_n, 1)

# Create descriptive labels
class_labels <- paste0("Class ", names(class_counts), " (", class_props, "%)")

# Map class numbers to labels
class_label_map <- setNames(class_labels, paste0("Class ", names(class_counts)))

# Step 3: Prepare data for plotting
means_long <- means_df %>%
  mutate(Indicator = param,
         Class = paste0("Class ", LatentClass)) %>%
  select(Indicator, Class, est) %>%
  pivot_wider(names_from = Class, values_from = est) %>%
  pivot_longer(cols = starts_with("Class"), names_to = "Class", values_to = "Mean")

# Apply the new labels
means_long$Class <- class_label_map[means_long$Class]

# Optional: Set indicator order
means_long$Indicator <- factor(means_long$Indicator)
# means_long$Indicator <- factor(means_long$Indicator,
#                                 levels = c("Eco", "Bio_PN", "Bio_IPI", "Bio_VRtN"))

# Step 4: Plot
ggplot(means_long, aes(x = Indicator, y = Mean, group = Class, color = Class)) +
  geom_line(size = 1) +
  geom_point(size = 2) +
  theme_minimal() +
  labs(title = "Latent Class Profile Plot",
       x = "Items",
       y = "Estimated Means") +
  theme(text = element_text(size = 14),
        axis.text.x = element_text(angle = 45, hjust = 1),
        legend.title = element_blank())
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.

class_counts

  1   2   3   4 
 40  82  75 101 
class_counts / nrow(dat)

        1         2         3         4 
0.1342282 0.2751678 0.2516779 0.3389262 

we chose the 4 class solution as the best model

setwd("outputs/LCA_means")


dat_classes <- read.table(file = "lca_4_choosen.txt")
dat$lclasses_BioEco <- dat_classes$V9

9.2 check relation to framing condition

classes_tables <- table(dat$lclasses_BioEco, dat$framingCondition)
classes_tables
   
    bio-inspired tech-inspired
  1           14            26
  2           32            50
  3           58            17
  4           56            45
chi <- chisq.test(classes_tables, correct = FALSE)
chi_stat <- chi$statistic
chi

    Pearson's Chi-squared test

data:  classes_tables
X-squared = 29.7, df = 3, p-value = 1.596e-06
# Cramer's V
n <- sum(classes_tables)
k <- min(nrow(classes_tables), ncol(classes_tables))

cramers_v <- sqrt(chi_stat / (n * (k - 1)))
cramers_v
X-squared 
0.3156982 
# Extract standardized residuals
std_res <- chi$stdres
round(std_res, 2)  # rounded for readability
   
    bio-inspired tech-inspired
  1        -2.55          2.55
  2        -3.13          3.13
  3         4.75         -4.75
  4         0.43         -0.43
# See which cells are "large" (e.g., |residual| > 2)
which(abs(std_res) > 2, arr.ind = TRUE)
  row col
1   1   1
2   2   1
3   3   1
1   1   2
2   2   2
3   3   2
# A heatmap of standardized residuals with ggplot2

res_df <- as.data.frame(as.table(std_res))
colnames(res_df) <- c("lclasses_BioEco", "framingCondition", "stdres")

ggplot(res_df, aes(x = framingCondition,
                   y = lclasses_BioEco,
                   fill = stdres)) +
  geom_tile() +
  geom_text(aes(label = round(stdres, 2))) +
  scale_fill_gradient2(
    low = "blue",
    mid = "white",
    high = "red",
    midpoint = 0
  ) +
  labs(
    title = "Standardized residuals: lclasses_BioEco × framingCondition",
    x = "Framing condition",
    y = "lclasses_BioEco",
    fill = "Std. resid"
  ) +
  theme_minimal()

9.3 check relation to mean scales

# ---- settings ----
class_var <- "lclasses_BioEco"  # <-- change if your membership column is named differently

# Ensure class is a factor
dat[[class_var]] <- as.factor(dat[[class_var]])

# Grab all mean_* variables
mean_vars <- str_subset(colnames(dat), "^mean")

# Helper: eta^2 from one-way ANOVA (SS_between / SS_total)
eta_sq_oneway <- function(aov_obj) {
  ss <- summary(aov_obj)[[1]][, "Sum Sq"]
  names(ss) <- rownames(summary(aov_obj)[[1]])
  ss_between <- ss[1]                 # first row = class factor
  ss_total   <- sum(ss, na.rm = TRUE) # between + residual
  as.numeric(ss_between / ss_total)
}

# Run ANOVAs and build compact results table
anova_table <- lapply(mean_vars, function(dv) {
  d <- dat %>% select(all_of(c(class_var, dv))) %>% tidyr::drop_na()

  # Skip if DV has no variance or only 1 class present after NA drop
  if (n_distinct(d[[dv]]) < 2 || n_distinct(d[[class_var]]) < 2) return(NULL)

  fit <- aov(reformulate(class_var, response = dv), data = d)
  sm  <- summary(fit)[[1]]

  tibble(
    dv      = dv,
    n       = nrow(d),
    k       = n_distinct(d[[class_var]]),
    df1     = sm[1, "Df"],
    df2     = sm[2, "Df"],
    F       = sm[1, "F value"],
    p       = sm[1, "Pr(>F)"],
    eta_sq  = eta_sq_oneway(fit)
  )
}) %>% bind_rows() %>%
  mutate(
    p_adj = p.adjust(p, method = "BH")  # optional multiple-testing control
  ) %>%
  arrange(p)

anova_table
# A tibble: 12 × 9
   dv                        n     k   df1   df2      F        p eta_sq    p_adj
   <chr>                 <int> <int> <dbl> <dbl>  <dbl>    <dbl>  <dbl>    <dbl>
 1 mean_Bioinspiration     298     4     3   294 351.   8.22e-97 0.782  9.86e-96
 2 mean_Bioinspiration_…   298     4     3   294 242.   4.31e-79 0.712  2.59e-78
 3 mean_Bioinspiration_…   298     4     3   294 218.   2.19e-74 0.690  8.77e-74
 4 mean_Bioinspiration_…   298     4     3   294 170.   5.76e-64 0.635  1.73e-63
 5 mean_video_sitintDes…   298     4     3   294  24.5  3.74e-14 0.200  8.98e-14
 6 mean_video_evalInf      298     4     3   294  22.3  4.94e-13 0.185  9.88e-13
 7 mean_video_sitintTop…   298     4     3   294  21.7  9.95e-13 0.181  1.71e-12
 8 mean_Ecological         298     4     3   294  20.4  5.20e-12 0.172  7.79e-12
 9 mean_GAToRS_pp          298     4     3   294  14.9  4.82e- 9 0.132  6.43e- 9
10 mean_GAToRS_sp          298     4     3   294   8.09 3.39e- 5 0.0763 4.07e- 5
11 mean_GAToRS_pn          298     4     3   294   5.66 8.80e- 4 0.0546 9.60e- 4
12 mean_GAToRS_sn          298     4     3   294   3.84 1.01e- 2 0.0378 1.01e- 2

9.3.1 for video: Situational Interest Scale - Design

# --- ANOVA for Ecological Dimension - PN ---
aov_out <- aov_ez(
  id = "PROLIFIC_PID",  # replace with your participant ID column name
  dv = "mean_video_sitintDesign",
  data = dat,
  between = "lclasses_BioEco"
)
print(aov_out)
Anova Table (Type 3 tests)

Response: mean_video_sitintDesign
           Effect     df  MSE         F  ges p.value
1 lclasses_BioEco 3, 294 1.12 24.45 *** .200   <.001
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1
# Post hoc (Tukey) for Ecological
em_eco <- emmeans(aov_out, "lclasses_BioEco")
eco_posthoc <- pairs(em_eco, adjust = "tukey")
print(eco_posthoc)
 contrast                            estimate    SE  df t.ratio p.value
 lclasses_BioEco1 - lclasses_BioEco2  -0.7788 0.204 294  -3.814  0.0010
 lclasses_BioEco1 - lclasses_BioEco3  -0.7503 0.207 294  -3.620  0.0020
 lclasses_BioEco1 - lclasses_BioEco4  -1.5851 0.198 294  -8.015  <.0001
 lclasses_BioEco2 - lclasses_BioEco3   0.0285 0.169 294   0.168  0.9983
 lclasses_BioEco2 - lclasses_BioEco4  -0.8063 0.157 294  -5.124  <.0001
 lclasses_BioEco3 - lclasses_BioEco4  -0.8348 0.161 294  -5.174  <.0001

P value adjustment: tukey method for comparing a family of 4 estimates 
# Summarize means and SE for plotting
plot_data <- data_summary(dat, "mean_video_sitintDesign", "lclasses_BioEco")

# --- Plot ---
ggplot(plot_data, aes(x = lclasses_BioEco, y = mean_video_sitintDesign)) +
  geom_col(fill = "grey80", color = "black", width = 0.6) +
  geom_errorbar(aes(ymin = mean_video_sitintDesign - se, ymax = mean_video_sitintDesign + se), width = 0.15) +
  labs(x = "Class Assignment", y = "Mean Score") +
  theme_apa() +
  theme(
    axis.title = element_text(face = "bold"),
    legend.position = "none"
  )

9.3.2 for mean_GAToRS_pp

# --- ANOVA for Ecological Dimension - PN ---
aov_out <- aov_ez(
  id = "PROLIFIC_PID",  # replace with your participant ID column name
  dv = "mean_GAToRS_pp",
  data = dat,
  between = "lclasses_BioEco"
)
print(aov_out)
Anova Table (Type 3 tests)

Response: mean_GAToRS_pp
           Effect     df  MSE         F  ges p.value
1 lclasses_BioEco 3, 294 0.93 14.88 *** .132   <.001
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1
# Post hoc (Tukey) for Ecological
em_eco <- emmeans(aov_out, "lclasses_BioEco")
eco_posthoc <- pairs(em_eco, adjust = "tukey")
print(eco_posthoc)
 contrast                            estimate    SE  df t.ratio p.value
 lclasses_BioEco1 - lclasses_BioEco2   -0.963 0.186 294  -5.186  <.0001
 lclasses_BioEco1 - lclasses_BioEco3   -0.552 0.189 294  -2.926  0.0193
 lclasses_BioEco1 - lclasses_BioEco4   -1.101 0.180 294  -6.119  <.0001
 lclasses_BioEco2 - lclasses_BioEco3    0.411 0.154 294   2.674  0.0394
 lclasses_BioEco2 - lclasses_BioEco4   -0.138 0.143 294  -0.963  0.7708
 lclasses_BioEco3 - lclasses_BioEco4   -0.549 0.147 294  -3.742  0.0013

P value adjustment: tukey method for comparing a family of 4 estimates 
# Summarize means and SE for plotting
plot_data <- data_summary(dat, "mean_GAToRS_pp", "lclasses_BioEco")

# --- Plot ---
ggplot(plot_data, aes(x = lclasses_BioEco, y = mean_GAToRS_pp)) +
  geom_col(fill = "grey80", color = "black", width = 0.6) +
  geom_errorbar(aes(ymin = mean_GAToRS_pp - se, ymax = mean_GAToRS_pp + se), width = 0.15) +
  labs(x = "Class Assignment", y = "Mean Score") +
  theme_apa() +
  theme(
    axis.title = element_text(face = "bold"),
    legend.position = "none"
  )

10 Open Text Answers

get word count:

dat$word_count_ecological <- sapply(dat$reflection_ecological, function(x) {
  length(strsplit(x, "\\s+")[[1]])
})
dat$word_count_social <- sapply(dat$reflection_social, function(x) {
  length(strsplit(x, "\\s+")[[1]])
})
dat$word_count_economic <- sapply(dat$reflection_economic, function(x) {
  length(strsplit(x, "\\s+")[[1]])
})

psych::describe(x = dat[, str_subset(string = colnames(dat), pattern = "^word_count")])
                      vars   n  mean    sd median trimmed   mad min max range
word_count_ecological    1 298 34.26 22.01     30   31.38 17.79   4 132   128
word_count_social        2 298 35.23 24.47     29   31.98 20.76   2 165   163
word_count_economic      3 298 35.68 24.22     30   32.10 19.27   3 136   133
                      skew kurtosis   se
word_count_ecological 1.50     2.90 1.27
word_count_social     1.63     4.09 1.42
word_count_economic   1.66     3.33 1.40

get sentiment:

# library(sentimentr)

sentiment_scores <- sentiment_by(dat$reflection_ecological)
dat$sentiment_ecological <- sentiment_scores$ave_sentiment

sentiment_scores <- sentiment_by(dat$reflection_social)
dat$sentiment_social <- sentiment_scores$ave_sentiment

sentiment_scores <- sentiment_by(dat$reflection_economic)
dat$sentiment_economic <- sentiment_scores$ave_sentiment

psych::describe(x = dat[, str_subset(string = colnames(dat), pattern = "^sentiment")])
                     vars   n mean   sd median trimmed  mad   min  max range
sentiment_ecological    1 298 0.20 0.29   0.18    0.19 0.24 -0.62 1.27  1.88
sentiment_social        2 298 0.27 0.34   0.25    0.25 0.30 -1.03 1.56  2.59
sentiment_economic      3 298 0.33 0.30   0.31    0.32 0.27 -0.64 1.19  1.83
                     skew kurtosis   se
sentiment_ecological 0.41     0.81 0.02
sentiment_social     0.61     2.08 0.02
sentiment_economic   0.17     0.52 0.02

10.1 Correlations

psych::describe(x = dat[, str_subset(string = colnames(dat), pattern = "^word_count")])
                      vars   n  mean    sd median trimmed   mad min max range
word_count_ecological    1 298 34.26 22.01     30   31.38 17.79   4 132   128
word_count_social        2 298 35.23 24.47     29   31.98 20.76   2 165   163
word_count_economic      3 298 35.68 24.22     30   32.10 19.27   3 136   133
                      skew kurtosis   se
word_count_ecological 1.50     2.90 1.27
word_count_social     1.63     4.09 1.42
word_count_economic   1.66     3.33 1.40
# Select variables of interest
vars_for_corr <- dat[, c(
  "mean_Bioinspiration",
  "mean_Bioinspiration_PN",
  "mean_Bioinspiration_IPI",
  "mean_Bioinspiration_VRtN",
  "mean_Ecological",
  "word_count_ecological",
  "word_count_social",
  "word_count_economic",
  "sentiment_ecological",
  "sentiment_social",
  "sentiment_economic"
)]

# Correlation matrix
cor_matrix <- cor(vars_for_corr, use = "pairwise.complete.obs")

psych::corPlot(r = cor_matrix)

10.2 SDGs

# run sdg detection
hits_ecological <- text2sdg::detect_sdg_systems(dat$reflection_ecological)
Warning in transparent_trim(x, remember_spaces): Leading and trailing
whitespace has been trimmed for 70 items.
Running Aurora
Running Elsevier
Running Auckland
Running SIRIS
# create barplot
plot_sdg(hits_ecological, remove_duplicates = FALSE)

# create barplot with facets
plot_sdg(hits_ecological, remove_duplicates = FALSE) + ggplot2::facet_wrap(~system)

# run sdg detection
hits_social <- text2sdg::detect_sdg_systems(dat$reflection_social)
Warning in transparent_trim(x, remember_spaces): Leading and trailing
whitespace has been trimmed for 72 items.
Running Aurora
Running Elsevier
Running Auckland
Running SIRIS
# create barplot
plot_sdg(hits_social, remove_duplicates = FALSE)

# create barplot with facets
plot_sdg(hits_social, remove_duplicates = FALSE) + ggplot2::facet_wrap(~system)

# run sdg detection
hits_economic <- text2sdg::detect_sdg_systems(dat$reflection_economic)
Warning in transparent_trim(x, remember_spaces): Leading and trailing
whitespace has been trimmed for 74 items.
Running Aurora
Running Elsevier
Running Auckland
Running SIRIS
# create barplot
plot_sdg(hits_economic, remove_duplicates = FALSE)

# create barplot with facets
plot_sdg(hits_economic, remove_duplicates = FALSE) + ggplot2::facet_wrap(~system)

10.3 SDGs <-> framing, classes

# 1) Keep only SIRIS hits and join to participant-level data
hits_siris <- hits_ecological %>%
  filter(system == "SIRIS") %>%
  mutate(ID = as.integer(as.character(document)))  # document is a factor in your tibble

dat_key <- dat %>%
  select(ID, framingCondition, lclasses_BioEco) %>%
  mutate(
    ID = as.integer(ID),
    framingCondition = factor(framingCondition),
    lclasses_BioEco = factor(lclasses_BioEco)
  )

hits_joined <- hits_siris %>%
  left_join(dat_key, by = "ID")

# 2) Collapse to a binary "mentioned SDG" per participant (recommended for hypothesis tests)
sdg_bin <- hits_joined %>%
  mutate(sdg = factor(sdg)) %>%
  group_by(ID, framingCondition, lclasses_BioEco, sdg) %>%
  dplyr::summarise(mentioned = 1L, .groups = "drop") %>%
  tidyr::complete(ID, framingCondition, lclasses_BioEco, sdg, fill = list(mentioned = 0L))

# -------------------------
# Hypothesis tests
# -------------------------

# A) SDG distribution differs by framingCondition? (Chi-square on SDG x framing)
tab_frame <- sdg_bin %>%
  group_by(sdg, framingCondition) %>%
  dplyr::summarise(n = sum(mentioned), .groups = "drop") %>%
  pivot_wider(names_from = framingCondition, values_from = n, values_fill = 0) %>%
  tibble::column_to_rownames("sdg") %>%
  as.matrix()

chi_frame <- chisq.test(tab_frame)
Warning in chisq.test(tab_frame): Chi-Quadrat-Approximation kann inkorrekt sein
chi_frame

    Pearson's Chi-squared test

data:  tab_frame
X-squared = 9.8478, df = 7, p-value = 0.1974
# B) SDG distribution differs by latent class? (Chi-square on SDG x class)
tab_class <- sdg_bin %>%
  group_by(sdg, lclasses_BioEco) %>%
  dplyr::summarise(n = sum(mentioned), .groups = "drop") %>%
  pivot_wider(names_from = lclasses_BioEco, values_from = n, values_fill = 0) %>%
  tibble::column_to_rownames("sdg") %>%
  as.matrix()

tab_class
       1 2 3 4
SDG-07 2 4 1 8
SDG-08 1 1 4 2
SDG-09 0 0 1 0
SDG-11 0 0 1 1
SDG-12 1 5 3 6
SDG-13 1 3 6 3
SDG-14 0 0 0 1
SDG-15 1 2 1 3
chi_class <- chisq.test(tab_class)
Warning in chisq.test(tab_class): Chi-Quadrat-Approximation kann inkorrekt sein
chi_class

    Pearson's Chi-squared test

data:  tab_class
X-squared = 15.36, df = 21, p-value = 0.8044
# C) Joint test: SDG differs across framing *and* class (multinomial logistic regression)
#    Outcome = SDG category; predictors = framingCondition + lclasses_BioEco (+ interaction)
library(nnet)

sdg_mentions <- sdg_bin %>%
  filter(mentioned == 1) %>%
  select(ID, sdg, framingCondition, lclasses_BioEco)

m0 <- multinom(sdg ~ 1, data = sdg_mentions, trace = FALSE)
m1 <- multinom(sdg ~ framingCondition + lclasses_BioEco, data = sdg_mentions, trace = FALSE)
m2 <- multinom(sdg ~ framingCondition * lclasses_BioEco, data = sdg_mentions, trace = FALSE)

anova(m0, m1, test = "Chisq")  # overall main effects vs intercept-only
Likelihood ratio tests of Multinomial Models

Response: sdg
                               Model Resid. df Resid. Dev   Test    Df LR stat.
1                                  1       427   219.3066                      
2 framingCondition + lclasses_BioEco       399   192.5429 1 vs 2    28 26.76364
    Pr(Chi)
1          
2 0.5311443
anova(m1, m2, test = "Chisq")  # adds interaction
Likelihood ratio tests of Multinomial Models

Response: sdg
                               Model Resid. df Resid. Dev   Test    Df LR stat.
1 framingCondition + lclasses_BioEco       399   192.5429                      
2 framingCondition * lclasses_BioEco       378   176.0974 1 vs 2    21 16.44552
    Pr(Chi)
1          
2 0.7441201
# Optional: which SDGs drive chi-square differences (standardized residuals)
round(chi_frame$stdres, 2)
       bio-inspired tech-inspired
SDG-07        -1.34          1.34
SDG-08         0.85         -0.85
SDG-09        -1.27          1.27
SDG-11         1.14         -1.14
SDG-12        -0.73          0.73
SDG-13         1.94         -1.94
SDG-14        -1.27          1.27
SDG-15        -0.24          0.24
round(chi_class$stdres, 2)
           1     2     3     4
SDG-07  0.55  0.26 -2.07  1.34
SDG-08  0.29 -0.83  1.53 -0.85
SDG-09 -0.33 -0.57  1.64 -0.80
SDG-11 -0.47 -0.81  0.73  0.33
SDG-12 -0.45  0.95 -0.74  0.12
SDG-13 -0.27 -0.11  1.70 -1.30
SDG-14 -0.33 -0.57 -0.62  1.27
SDG-15  0.44  0.29 -0.83  0.24