# one package below requires that you use devtools to install them manually:# first install devtools by# install.packages('devtools')library(RISEkbmRasch) # devtools::install_github("pgmj/RISEkbmRasch")library(grateful)library(ggrepel)library(car)library(kableExtra)library(readxl)library(tidyverse)library(eRm)library(mirt)library(psych)library(psychotree)library(matrixStats)library(reshape)library(knitr)library(patchwork)library(formattable) library(glue)library(haven)library(labelled)library(qualtRics)library(janitor)library(lavaanExtra)library(lavaan)library(lavaanPlot)library(parameters)library(marginaleffects)library(modelsummary)library(showtext)library(broom)source("theme_prevent.R")### optional libraries#library(TAM)#library(skimr)### some commands exist in multiple packages, here we define preferred ones that are frequently usedselect <- dplyr::selectcount <- dplyr::countrecode <- car::recoderename <- dplyr::renameannotate <- ggplot2::annotatesource("RISE_theme.R")
Code
# import item informationdf <-read_spss("data/prevent_safety_itemlabels.sav")# get metadata into a separate dataframeitem <-lapply(df, function(x) attributes(x)$label)itemlabels_all <-data.frame(itemnr =names(df),item =unlist(item),row.names =NULL)itemlabels <- itemlabels_all %>%filter(str_detect(itemnr, 'q1|q2|q3|q4')) %>%separate_wider_delim(item, names =c(NA,"item"), delim =". - ")
# recode to numericsdf2 <- df %>%select(!q5a) %>%#select(!q5b) %>% #fritextsvar bortplockademutate(across(starts_with("q"), ~ car::recode(.x,"'Stämmer helt'=3;'Stämmer ganska väl'=2;'Stämmer ganska dåligt'=1;'Stämmer inte alls'=0", as.factor =FALSE)))
1 Introduktion till analys
1.1 Kort om analysmetod
RISE har tagit fram fem grundläggande psykometriska kriterier som har varit utgångspunkt för analysarbetet. En artikel som beskriver kriterierna finns fritt tillgänglig som preprint (Johansson et al. 2023) och innehåller både en enklare och mera fördjupad beskrivning av kriterierna.
Nedan finns en förenklad beskrivning av de psykometriska kriterierna på svenska, som kommer från RISE rapport till MFoF om uppföljning av föräldraskapsstöd (Preuter, Johansson, and Bokström 2022):
När enkäter konstrueras och utvärderas bedöms dess psykometriska egenskaper, ofta kopplade till begreppen reliabilitet och validitet. Förenklat kan man säga att reliabilitet beskriver hur väl något mäts (vilken precision mätverktyget har), medan validitet beskriver hur väl innehållet i frågorna och svarskategorierna fångar det man avser att mäta. Dock råder i allmänhet oklara definitioner av begreppen och kriterier för huruvida dessa mätegenskaper uppfylls eller inte. Det medför att även enkäter som i forskningsartiklar beskrivs som “validerade” eller att de har “god reliabilitet” inte nödvändigtvis uppfyller vad som kan anses vara grundläggande kriterier. En mera omfattande beskrivning av de grundläggande psykometriska kriterierna återfinns i Bilaga 3 (separat dokument). Nedan listas kriterierna. Var och en av dem kräver psykometrisk analys av insamlade data för att bedöma.
Lista över grundläggande psykometriska kriterier:
Svarskategorierna fungerar som avsett
Frågorna fungerar likadant för olika grupper (kön, ålder, etc)
Unidimensionalitet (utan för starkt korrelerade residualer)
Reliabilitet/mätosäkerheter över skalans omfång är adekvat, sett till användningsområdet
Omvandlingstabell till intervallskala
Kriterierna ovan är ställda för att säkerställa att det är lämpligt att använda summapoäng från en enkät/skala. Summapoängen bör i sin tur användas tillsammans med en omvandlingstabell till intervallskala innan några statistiska eller matematiska beräkningar görs. Tyvärr är det mycket vanligt att forskningsstudier enbart redovisar Cronbach’s alpha som ett mått på reliabilitet och/eller kvalitet på en enkät. Det är dessvärre gravt otillräckligt för att bedöma mätegenskaper hos ett mätverktyg, eftersom Cronbach’s alpha inte ger information om något av kriterierna ovan.
Det är många som har missing data rakt igenom. Detta kan bero på att länken är öppen och tillgänglig även för “bottar” på internet, samt de som enbart är intresserade av att titta på frågorna men ej besvara dem.
Vi har mycket låg representation av åldersgruppen 19-29.
Code
# create DIF-variablesdif_age <-factor(df_dif$age)# too few responses in other gender groups, need to recode to missingdif_gender <- df_dif %>%mutate(gender =recode(gender,"'Vill ej ange'=NA;'Annat'=NA", as.factor =TRUE)) %>%pull(gender)dif_role <-factor(df_dif$role)dif_bransch <-factor(df_dif$bransch)
4 Analys steg 1
4.1 Q1 Ledningens engagemang
Code
df.delskala <- d %>%select(starts_with("q1"))
4.1.1 Deskriptiv statistik
Code
RIallresp(df.delskala)
Response category
Number of responses
Percent
0
56
6.0
1
236
25.5
2
367
39.6
3
268
28.9
4.1.2 Descriptives - item level
Code
RIlistItemsMargin(df.delskala, fontsize =12)
itemnr
item
q1_1
Ledningen uppmuntrar medarbetarna att arbeta säkert även i perioder när schemat är pressat.
q1_2
Ledningen involverar medarbetarna i beslut som rör säkerheten.
q1_3
Ledningen visar i sitt agerande att säkerhet alltid prioriteras högt.
The eRm package, which uses Conditional Maximum Likelihood (CML) estimation, will be used primarily. For this analysis, the Partial Credit Model will be used.
itemnr
item
q1_1
Ledningen uppmuntrar medarbetarna att arbeta säkert även i perioder när schemat är pressat.
q1_2
Ledningen involverar medarbetarna i beslut som rör säkerheten.
q1_3
Ledningen visar i sitt agerande att säkerhet alltid prioriteras högt.
The eRm package, which uses Conditional Maximum Likelihood (CML) estimation, will be used primarily. For this analysis, the Partial Credit Model will be used.
itemnr
item
q2_1
Jag anser att ambitionen att minska antalet olyckor genomsyrar det dagliga arbetet.
q2_2
Min närmsta chef har stort fokus på att kritisera misstag.
q2_3
Min närmsta chef berömmer oss ofta när vi jobbar säkert.
q2_4
Min närmsta chef påminner mig om att följa säkerhetsreglerna även i pressade situationer.
q2_5
Min närmsta chef lyssnar och agerar när jag berättar om något som inte fungerar gällande säkerheten.
q2_6
Min närmsta chef involverar mig i att prata om säkra beteenden och hur vi ska agera för att en olycka inte skall inträffa.
Relative cut-off value (highlighted in red) is 0.044, which is 0.2 above the average correlation.
Code
RIloadLoc(df.delskala)
Code
RIitemCats(df.delskala)
Code
# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)
Code
RIitemHierarchy(df.delskala)
Code
RIdifTable(df.delskala, dif_gender)
[1] "No significant DIF found."
Code
RIdifTable(df.delskala, dif_age)
[1] "No significant DIF found."
Code
RIdifTable(df.delskala, dif_role)
[1] "No significant DIF found."
Code
RIdifTable(df.delskala, dif_bransch)
[1] "No significant DIF found."
Code
RIpfit(df.delskala)
Item q2_2 “Min närmsta chef har stort fokus på att kritisera misstag.” avviker ur konstruktet. Mycket hög item fit och avvikande laddning på första kontrastfaktorn.
Residualkorrelation mellan q2_4 och q2_6
q2_4 Min närmsta chef påminner mig om att följa säkerhetsreglerna även i pressade situationer.
q2_6 Min närmsta chef involverar mig i att prata om säkra beteenden och hur vi ska agera för att en olycka inte skall inträffa.
4.5 Q3 Förutsättningar
Code
df.delskala <- d %>%select(starts_with("q3"))
4.5.1 Deskriptiv statistik
Code
RIallresp(df.delskala)
Response category
Number of responses
Percent
0
118
5.5
1
459
21.2
2
963
44.5
3
623
28.8
4.5.2 Descriptives - item level
Code
RIlistItemsMargin(df.delskala, fontsize =12)
itemnr
item
q3_1
Jag får de instruktioner och den vägledning jag behöver för att kunna utföra arbetet på ett säkert sätt.
q3_2
De säkerhetsföreskrifter och regler som gäller på vår arbetsplats är lätta att förstå och följa.
q3_3
Jag upplever att jag har rätt förutsättningar för att kunna jobba säkert.
q3_4
Jag upplever att jag har rätt kompetens för att kunna jobba säkert.
q3_5
Jag upplever att jag har tillräckligt med tid för att kunna jobba säkert.
q3_6
Jag upplever att jag har tillgång till korrekt utrustning för att kunna jobba säkert.
The eRm package, which uses Conditional Maximum Likelihood (CML) estimation, will be used primarily. For this analysis, the Partial Credit Model will be used.
itemnr
item
q3_1
Jag får de instruktioner och den vägledning jag behöver för att kunna utföra arbetet på ett säkert sätt.
q3_2
De säkerhetsföreskrifter och regler som gäller på vår arbetsplats är lätta att förstå och följa.
q3_3
Jag upplever att jag har rätt förutsättningar för att kunna jobba säkert.
q3_4
Jag upplever att jag har rätt kompetens för att kunna jobba säkert.
q3_5
Jag upplever att jag har tillräckligt med tid för att kunna jobba säkert.
q3_6
Jag upplever att jag har tillgång till korrekt utrustning för att kunna jobba säkert.
Relative cut-off value (highlighted in red) is 0.052, which is 0.2 above the average correlation.
Code
RIloadLoc(df.delskala)
Code
RIitemCats(df.delskala)
Code
# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)
Code
RIitemHierarchy(df.delskala)
Code
RIdifTable(df.delskala, dif_gender)
[1] "No significant DIF found."
Code
RIdifTable(df.delskala, dif_age)
[1] "No significant DIF found."
Code
RIdifTable(df.delskala, dif_role)
Item
2
3
Mean location
StDev
MaxDiff
q3_1
-0.071
0.283
0.106
0.251
0.354
q3_2
0.235
0.293
0.264
0.041
0.058
q3_3
0.999
0.101
0.550
0.635
0.898
q3_4
-1.010
-1.475
-1.243
0.329
0.465
q3_5
0.620
0.347
0.484
0.193
0.273
q3_6
-0.544
-0.313
-0.428
0.164
0.231
q3_7
-0.228
0.763
0.268
0.701
0.992
Code
RIdifTable(df.delskala, dif_bransch)
[1] "No significant DIF found."
Code
RIpfit(df.delskala)
q3_3 har låg item fit, vilket är väntat med när ett generellt item kombineras med mera specifika items som mäter aspekter av samma sak. I övrigt ser allt ok ut, möjligen undantaget DIF för roll.
4.7 Q4 Säkert medarbetarskap
Code
df.delskala <- d %>%select(starts_with("q4"))
4.7.1 Deskriptiv statistik
Code
RIallresp(df.delskala)
Response category
Number of responses
Percent
0
136
7.3
1
453
24.4
2
793
42.8
3
472
25.5
4.7.2 Descriptives - item level
Code
RIlistItemsMargin(df.delskala, fontsize =12)
itemnr
item
q4_1
Vi hjälper varandra att jobba säkert även under stressiga perioder.
q4_2
När vi ser någon arbeta riskfyllt säger vi till personen.
q4_3
Som medarbetare visar vi uppskattning när någon arbetar säkert.
q4_4
Ibland tar vi genvägar i arbetet för att arbetsvardagen ska bli smidigare, även om det kan innebära ökad risk.
q4_5
Jag kan påpeka brister i säkerheten utan rädsla för negativa konsekvenser.
q4_6
Vi som arbetar här tar varandras synpunkter och förslag rörande säkerhet på allvar.
The eRm package, which uses Conditional Maximum Likelihood (CML) estimation, will be used primarily. For this analysis, the Partial Credit Model will be used.
itemnr
item
q4_1
Vi hjälper varandra att jobba säkert även under stressiga perioder.
q4_2
När vi ser någon arbeta riskfyllt säger vi till personen.
q4_3
Som medarbetare visar vi uppskattning när någon arbetar säkert.
q4_4
Ibland tar vi genvägar i arbetet för att arbetsvardagen ska bli smidigare, även om det kan innebära ökad risk.
q4_5
Jag kan påpeka brister i säkerheten utan rädsla för negativa konsekvenser.
q4_6
Vi som arbetar här tar varandras synpunkter och förslag rörande säkerhet på allvar.
Relative cut-off value (highlighted in red) is -0.012, which is 0.2 above the average correlation.
Code
RIloadLoc(df.delskala)
Code
RIitemCats(df.delskala)
Code
# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)
Code
RIitemHierarchy(df.delskala)
Code
RIdifTable(df.delskala, dif_gender)
[1] "No significant DIF found."
Code
RIdifTable(df.delskala, dif_age)
[1] "No significant DIF found."
Code
RIdifTable(df.delskala, dif_role)
[1] "No significant DIF found."
Code
RIdifTable(df.delskala, dif_bransch)
[1] "No significant DIF found."
Code
RIpfit(df.delskala)
Code
RItif(df.delskala, cutoff =2)
Frågorna fungerar tillsammans, dock med låg reliabilitet och något låg item fit för två items.
I en norsk forskningsartikel av Ajslev och kollegor (2017) används fem frågor från NOSACQ-50 (Kines et al. 2011) som återfinns i den danska arbetsmiljöundersökningen NRCWE Arbejdsmiljø og Helbred 2012. Det verkar dock inte som att dessa fem items är samma som de fem som återfinns i Prevents enkät.
Det man gör i artikeln är att dikotomisera de fem frågorna, så de två negativa/positiva svarskategorierna slås samman, och så räknar man “antalet arbetsmiljöproblem” på en skala 0-5. Sedan används den variabeln för att undersöka samband med självrapporterade olyckor. Vårt dataset innehåller också en självrapporterad variabel gällande olycka, och vi återkommer till analys av samband längre fram i detta dokument.
Code
thetas_nosacq <-RIestThetas(df.delskala)
4.10 Explorativ analys
Även om vi har hypoteser om vilka items som ska hänga samman i separata områden finns ett intresse av att undersöka eventuella korsladdningar och annat.
Vi gör en konfirmatorisk faktoranalys för att kunna titta på modification indices, korsladdningar och residualkorrelationer i en multidimensionell modell.
Vi provar att lägga in alla 22 items i en Rasch-modell.
Code
df.delskala <- d
The eRm package, which uses Conditional Maximum Likelihood (CML) estimation, will be used primarily. For this analysis, the Partial Credit Model will be used.
itemnr
item
q1_1
Ledningen uppmuntrar medarbetarna att arbeta säkert även i perioder när schemat är pressat.
q1_2
Ledningen involverar medarbetarna i beslut som rör säkerheten.
q1_3
Ledningen visar i sitt agerande att säkerhet alltid prioriteras högt.
q2_1
Jag anser att ambitionen att minska antalet olyckor genomsyrar det dagliga arbetet.
q2_2
Min närmsta chef har stort fokus på att kritisera misstag.
q2_3
Min närmsta chef berömmer oss ofta när vi jobbar säkert.
q2_4
Min närmsta chef påminner mig om att följa säkerhetsreglerna även i pressade situationer.
q2_5
Min närmsta chef lyssnar och agerar när jag berättar om något som inte fungerar gällande säkerheten.
q2_6
Min närmsta chef involverar mig i att prata om säkra beteenden och hur vi ska agera för att en olycka inte skall inträffa.
q3_1
Jag får de instruktioner och den vägledning jag behöver för att kunna utföra arbetet på ett säkert sätt.
q3_2
De säkerhetsföreskrifter och regler som gäller på vår arbetsplats är lätta att förstå och följa.
q3_3
Jag upplever att jag har rätt förutsättningar för att kunna jobba säkert.
q3_4
Jag upplever att jag har rätt kompetens för att kunna jobba säkert.
q3_5
Jag upplever att jag har tillräckligt med tid för att kunna jobba säkert.
q3_6
Jag upplever att jag har tillgång till korrekt utrustning för att kunna jobba säkert.
q3_7
Jag upplever att risker åtgärdas när de påtalats.
q4_1
Vi hjälper varandra att jobba säkert även under stressiga perioder.
q4_2
När vi ser någon arbeta riskfyllt säger vi till personen.
q4_3
Som medarbetare visar vi uppskattning när någon arbetar säkert.
q4_4
Ibland tar vi genvägar i arbetet för att arbetsvardagen ska bli smidigare, även om det kan innebära ökad risk.
q4_5
Jag kan påpeka brister i säkerheten utan rädsla för negativa konsekvenser.
q4_6
Vi som arbetar här tar varandras synpunkter och förslag rörande säkerhet på allvar.
Relative cut-off value (highlighted in red) is 0.141, which is 0.2 above the average correlation.
Code
RIloadLoc(df.delskala)
Code
# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)
Code
RIitemHierarchy(df.delskala)
Det är tydligt att det finns multidimensionalitet i data, även efter att ha tagit bort våra mest problematiska items. Detta framgår utifrån PCA av residualer samt residualkorrelationer. Således avbryter vi denna explorativa analys.
5 Kommentarer steg 1
5.1 Generellt
Reverserade items (q4_4 och q2_2) funkar dåligt dimensionalitetsmässigt.
q2_2 Min närmsta chef har stort fokus på att kritisera misstag.
q4_4 Ibland tar vi genvägar i arbetet för att arbetsvardagen ska bli smidigare, även om det kan innebära ökad risk.
Ev. titta närmare på:
DIF för roll gällande “Förutsättningar”.
DIF för ålder gällande “Säkert Medarbetarskap”.
5.2 Ledningens engagemang
Låg reliabilitet p.g.a. få items. Låg item fit för två items.
5.3 Säkert ledarskap
Item q2_2 “Min närmsta chef har stort fokus på att kritisera misstag.” avviker ur konstruktet. Mycket hög item fit och avvikande laddning på första kontrastfaktorn.
Residualkorrelation mellan q2_4 och q2_6
q2_4 Min närmsta chef påminner mig om att följa säkerhetsreglerna även i pressade situationer.
q2_6 Min närmsta chef involverar mig i att prata om säkra beteenden och hur vi ska agera för att en olycka inte skall inträffa.
5.4 Förutsättningar
q3_3 har låg item fit, vilket är väntat med när ett generellt item kombineras med mera specifika items som mäter aspekter av samma sak. I övrigt ser allt ok ut, möjligen undantaget DIF för roll.
q3_3 kan tas bort. q3_4-6 hanterar området bättre pga högre specificitet (tydligare avgränsning) i frågeställningarna.
5.5 Säkert medarbetarskap
Item q4_4 avviker med hög item fit och laddning på första residualkontrasten. Passar inte in i konstruktet.
Residualkorrelation mellan items q4_5 och q4_6.
q4_5 Jag kan påpeka brister i säkerheten utan rädsla för negativa konsekvenser.
q4_6 Vi som arbetar här tar varandras synpunkter och förslag rörande säkerhet på allvar.
q4_6 har låg item fit och bör tas bort.
5.6 Utifrån EFA/CFA multidimensionell analys
q2_1 och q3_7 hänger mer ihop med q1 (ledningen), q3_7 även med q2 - q2_1 Jag anser att ambitionen att minska antalet olyckor genomsyrar det dagliga arbetet. - q3_7 Jag upplever att risker åtgärdas när de påtalats.
Residualkorrelation mellan q3_7 och q2_5: - q2_5 Min närmsta chef lyssnar och agerar när jag berättar om något som inte fungerar gällande säkerheten.
q2_2 funkar som nämnt inte bra, men noterar intressant residualkorrelation med q4_5
q4_5 Jag kan påpeka brister i säkerheten utan rädsla för negativa konsekvenser.
q2_2 Min närmsta chef har stort fokus på att kritisera misstag.
q4_5 korsladdar på q3 i 4-faktors CFA
5.7 Åtgärder att testa
5.7.1 q2
q2_2 tas bort, q2_1 flyttas till q1
5.7.2 q3
q3_3 tas bort pga redundans. q3_7 flyttas till q1
5.7.3 q4
q4_5 har residualkorrelation med q4_6, kan ev fungera bättre i q3 så vi flyttar den dit.
q4_4 tas bort
6 Analys steg 2
6.1 Q1 Ledningens engagemang
q2_1 flyttas till q1
q3_7 flyttas till q1
Code
df.delskala <- d %>%select(starts_with("q1"),q2_1,q3_7)
itemnr
item
q1_1
Ledningen uppmuntrar medarbetarna att arbeta säkert även i perioder när schemat är pressat.
q1_2
Ledningen involverar medarbetarna i beslut som rör säkerheten.
q1_3
Ledningen visar i sitt agerande att säkerhet alltid prioriteras högt.
q2_1
Jag anser att ambitionen att minska antalet olyckor genomsyrar det dagliga arbetet.
# make a table similar to the one above, but add in itemlabels for item descriptionsitems_final_set <-data.frame(delskala =c(rep("Ledningens Engagemang", length(items_q1)),rep("Säkert ledarskap", length(items_q2)),rep("Förutsättningar", length(items_q3)),rep("Säkert medarbetarskap", length(items_q4)) ),itemnr =c(items_q1,items_q2,items_q3,items_q4),stringsAsFactors =FALSE) %>%left_join(itemlabels, by ="itemnr")items_final_set %>%kbl_rise() %>%collapse_rows(columns =1)
delskala
itemnr
item
Ledningens Engagemang
q1_1
Ledningen uppmuntrar medarbetarna att arbeta säkert även i perioder när schemat är pressat.
q1_2
Ledningen involverar medarbetarna i beslut som rör säkerheten.
q1_3
Ledningen visar i sitt agerande att säkerhet alltid prioriteras högt.
q2_1
Jag anser att ambitionen att minska antalet olyckor genomsyrar det dagliga arbetet.
q3_7
Jag upplever att risker åtgärdas när de påtalats.
Säkert ledarskap
q2_3
Min närmsta chef berömmer oss ofta när vi jobbar säkert.
q2_4
Min närmsta chef påminner mig om att följa säkerhetsreglerna även i pressade situationer.
q2_5
Min närmsta chef lyssnar och agerar när jag berättar om något som inte fungerar gällande säkerheten.
q2_6
Min närmsta chef involverar mig i att prata om säkra beteenden och hur vi ska agera för att en olycka inte skall inträffa.
Förutsättningar
q3_1
Jag får de instruktioner och den vägledning jag behöver för att kunna utföra arbetet på ett säkert sätt.
q3_2
De säkerhetsföreskrifter och regler som gäller på vår arbetsplats är lätta att förstå och följa.
q3_4
Jag upplever att jag har rätt kompetens för att kunna jobba säkert.
q3_5
Jag upplever att jag har tillräckligt med tid för att kunna jobba säkert.
q3_6
Jag upplever att jag har tillgång till korrekt utrustning för att kunna jobba säkert.
q4_5
Jag kan påpeka brister i säkerheten utan rädsla för negativa konsekvenser.
Säkert medarbetarskap
q4_1
Vi hjälper varandra att jobba säkert även under stressiga perioder.
q4_2
När vi ser någon arbeta riskfyllt säger vi till personen.
q4_3
Som medarbetare visar vi uppskattning när någon arbetar säkert.
q4_6
Vi som arbetar här tar varandras synpunkter och förslag rörande säkerhet på allvar.
Av de 22 items som prövats i denna analys har 3 tagits bort:
q2_2 Min närmsta chef har stort fokus på att kritisera misstag.
q3_3 Jag upplever att jag har rätt förutsättningar för att kunna jobba säkert.
q4_4 Ibland tar vi genvägar i arbetet för att arbetsvardagen ska bli smidigare, även om det kan innebära ökad risk.
Både q2_2 och q4_4 har tagits bort på grund av att de inte passar in, vilket delvis kan bero på att de är de enda negativt formulerade frågorna (som därmed har reverserad svarsskala i analysen). Gällande q3_3 hade den kunnat vara kvar, men delskalan fungerar tillräckligt bra utan den, och den tillförde relativt lite information eftersom det är en generell fråga om förutsättningar.
7.1 CFA nya delskalor
Vi gör en CFA på de nya delskalorna, och passar på att lägga till en “higher order” latent variabel utifrån de fyra delskalorna.
Tycker du att frågorna ovan täcker in det som är viktigt för att beskriva de grundläggande aspekterna av säkerhetskulturen på en arbetsplats?
q5b
Om du har förslag på frågor eller områden som saknas i enkäten, vänligen beskriv det här:
8.1 Kvantitativ fråga
Code
# svarskategorier <- df %>%# select(q5a) %>%# pivot_longer(everything()) %>%# na.omit() %>%# distinct(value) %>%# pull(value)total_n <- df %>%select(q5a) %>%na.omit() %>%nrow()q5a_long <- df %>%select(q5a) %>%pivot_longer(everything()) %>%na.omit() %>%count(name, value) %>%# räkna hur många individer i varje svarskategorimutate(Procent = (100* n /sum(n))) %>%# räkna fram procent för varje svarskategorimutate(across(where(is.numeric), ~round(.x, 2))) %>%rename(Svarskategori = value, # byt namn på variabler inför skapande av figur. Fråga = name ) %>%left_join(itemlabels, by =join_by("Fråga"=="itemnr"))q5a_long %>%ggplot(aes(x = Svarskategori, y = Procent, fill = Svarskategori)) +scale_y_continuous(limits =c(0, 75), breaks =seq(0, 100, 10)) +# starta alltid y på 0scale_x_discrete(guide =guide_axis(n.dodge =1),labels =~str_wrap(as.character(.x), 18) ) +geom_col() +geom_text(aes(label =paste0("n = ", n)),color ="darkgrey",size =4,position =position_dodge(width =0.9),vjust =-0.4 ) +scale_fill_viridis_d(direction =-1) +theme_minimal() +theme_prevent() +theme(legend.position ="none") +labs(title =str_wrap("Tycker du att frågorna täcker in det som är viktigt för att beskriva de grundläggande aspekterna av säkerhetskulturen på en arbetsplats?", 59),subtitle =paste0("Antal svar totalt: ", total_n,". Andel positiva: ", q5a_long[1, 4] + q5a_long[2, 4], "%." ),caption =str_wrap("Staplarnas höjd anger andel (%) av respondenterna som svarat i respektive svarskategori. Siffran ovanför staplarna anger antalet respondenter som svarat i den kategorin.", 100) )
total_n_q6 <- df %>%select(q6) %>%na.omit() %>%nrow()q6_long <- df %>%mutate(q6 =factor(q6,levels =c("Nej", "Ja, en gång", "Ja, två gånger", "Ja, tre gånger", "Ja, fyra gånger eller fler"),ordered =TRUE )) %>%select(q6) %>%pivot_longer(everything()) %>%na.omit() %>%count(name, value) %>%# räkna hur många individer i varje svarskategorimutate(Procent = (100* n /sum(n))) %>%# räkna fram procent för varje svarskategorimutate(across(where(is.numeric), ~round(.x, 2))) %>%rename(Svarskategori = value, # byt namn på variabler inför skapande av figur. Fråga = name ) %>%add_column(item ="Har du det senaste året varit med om en eller flera arbetsplatsolyckor som resulterat i mer än en dags frånvaro från arbetet?")q6_long %>%ggplot(aes(x = Svarskategori, y = Procent, fill = Svarskategori)) +scale_y_continuous(limits =c(0, 75), breaks =seq(0, 100, 10)) +# starta alltid y på 0geom_col() +geom_text(aes(label =paste0("n = ", n)),color ="darkgrey",size =4,position =position_dodge(width =0.9),vjust =-0.5 ) +scale_fill_viridis_d(direction =-1) +theme_minimal() +theme_prevent() +theme(legend.position ="none",panel.grid.major.x =element_blank(),panel.grid.minor.x =element_blank() ) +labs(title =str_wrap("Har du det senaste året varit med om en eller flera arbetsplatsolyckor som resulterat i mer än en dags frånvaro från arbetet?", 70),subtitle =paste0("Antal svar totalt: ", total_n_q6),caption =str_wrap("Staplarnas höjd anger andel (%) av respondenterna som svarat i respektive svarskategori. Siffran ovanför staplarna anger antalet respondenter (n) som svarat i den kategorin.", 100) )
# A tibble: 6 × 3
q6 q6dik n
<chr> <dbl> <int>
1 Ja, en gång 1 20
2 Ja, fyra gånger eller fler 1 16
3 Ja, tre gånger 1 5
4 Ja, två gånger 1 27
5 Nej 0 156
6 <NA> NA 85
Med övergripande “säkerhet” som latent variabel och prediktor för utfallet olycka (q6) dikotomiserat, d.v.s. där frekvensen av olyckor inte tas med, utan bara ja/nej. Vi har såpass få respondenter som angett att de varit med om olyckor att vi inte kan använda det mera graderade utfallet.
glm_all_theta <-glm(q6dik ~ thetas_q1 + thetas_q2 + thetas_q3 + thetas_q4, data = d_sem, family =binomial(link ="probit")) #probit is same as lavaan SEM usestidy(glm_all_theta)
Plot av rådata med jitter på den dikotomiserade variabeln (bara 0 och 1 är möjliga svar).
Code
ggplot( d_sem,aes(x = thetas_nosacq, y = q6dik)) +geom_jitter(width =0.02, height =0.02) +geom_smooth(method ="loess") +scale_y_continuous(breaks =c(0, 1)) +geom_vline(xintercept =1.5, linetype ="dashed") +labs(x ="Estimerade mätvärden (theta) för de fem NOSACQ-frågorna",y ="Varit med om olycka (1) eller inte(0)", title ="Rådata" )
Ser ut som att vi når “botten” vid nosacq theta = 1.5?
9.1.5.1 glm()
Vi passar på att testa de två R-paketen som implementerar Firth’s penalized logistic regression, som är allmänt rekommenderat vid mindre sampelstorlekar och/eller vid lågfrekventa utfall i data. Först kommer vanlig logistisk regression, sedan Firth’s justerade metod två gånger.
Code
glm_nosacq_theta <-glm(q6dik ~ thetas_nosacq, data = d_sem, family =binomial(link ="logit"))tidy(glm_nosacq_theta)
plot_predictions(glm_nosacq_theta, by ="thetas_nosacq") +#, transform = "exp")labs(x ="Estimerade mätvärden (theta) för de fem NOSACQ-frågorna",y ="Varit med om olycka (1) eller inte(0)", title ="Predicerade värden i statistisk modell", subtitle ="glm(q6dik ~ thetas_nosacq, data = d_sem, family = binomial(link = 'logit'))" )
Code
library(logistf)glm_nosacq_theta_p <-logistf(q6dik ~ thetas_nosacq, data = d_sem, family =binomial(link ="logit"))summary(glm_nosacq_theta_p)
logistf(formula = q6dik ~ thetas_nosacq, data = d_sem, family = binomial(link = "logit"))
Model fitted by Penalized ML
Coefficients:
coef se(coef) lower 0.95 upper 0.95 Chisq
(Intercept) -0.3653137 0.19464971 -0.7488053 0.01817077 3.488884
thetas_nosacq -0.2592295 0.07702015 -0.4138043 -0.11023716 11.721294
p method
(Intercept) 0.0617822231 2
thetas_nosacq 0.0006178899 2
Method: 1-Wald, 2-Profile penalized log-likelihood, 3-None
Likelihood ratio test=11.72129 on 1 df, p=0.0006178899, n=224
Wald test = 39.57521 on 1 df, p = 3.156649e-10
Code
library(brglm2)glm_nosacq_theta_p2 <-glm(q6dik ~ thetas_nosacq, data = d_sem, family =binomial(link ="logit"), method ="brglmFit")tidy(glm_nosacq_theta_p2)
plot_predictions(glm_nosacq_theta_p2, by ="thetas_nosacq") +#, transform = "exp")labs(x ="Estimerade mätvärden (theta) för de fem NOSACQ-frågorna",y ="Varit med om olycka (1) eller inte(0)", title ="Predicerade värden i statistisk modell", subtitle ="glm(q6dik ~ thetas_nosacq, data = d_sem, family = binomial(link = 'logit'), method = 'brglmFit')" )
Denna metod fångar inte “utplaningen” som sker efter x ~ 1.5, så vi behöver hitta en analysmetod som bättre passar data.
Här är nosacq_theta = 2 “botten”. Det ser också rimligt ut som gränsvärde utifrån targetingfiguren (sektion 4.11), och motsvarar att ha svarat nästa högsta svarsalternativet på alla fem frågorna.
Sum score 10 = svarsalternativ 2 på alla fem frågorna. Men även 8-9 verkar ge goda utfall (1-2 frågor med svar “Stämmer ganska dåligt”). Allt detta med reservation för att vi har ett litet sampel.
Mair and Hatzinger (2007b); Mair and Hatzinger (2007a); Hatzinger and Rusch (2009); Rusch, Maier, and Hatzinger (2013); Koller, Maier, and Hatzinger (2015); Debelak and Koller (2019)
Trepte and Verbeet (2010); Strobl, Wickelmaier, and Zeileis (2011); Strobl, Kopf, and Zeileis (2015); Komboz, Zeileis, and Strobl (2018); Wickelmaier and Zeileis (2018)
Ajslev, Jeppe, Efat Lali Dastjerdi, Johnny Dyreborg, Pete Kines, Katharina Christiane Jeschke, Emil Sundstrup, Markus Due Jakobsen, Nils Fallentin, and Lars Louis Andersen. 2017. “Safety Climate and Accidents at Work: Cross-Sectional Study Among 15,000 Workers of the General Working Population.”Safety Science 91 (January): 320–25. https://doi.org/10.1016/j.ssci.2016.08.029.
Allaire, JJ, Yihui Xie, Christophe Dervieux, Jonathan McPherson, Javier Luraschi, Kevin Ushey, Aron Atkins, et al. 2024. rmarkdown: Dynamic Documents for r. https://github.com/rstudio/rmarkdown.
Arel-Bundock, Vincent. 2022. “modelsummary: Data and Model Summaries in R.”Journal of Statistical Software 103 (1): 1–23. https://doi.org/10.18637/jss.v103.i01.
Chalmers, R. Philip. 2012. “mirt: A Multidimensional Item Response Theory Package for the R Environment.”Journal of Statistical Software 48 (6): 1–29. https://doi.org/10.18637/jss.v048.i06.
Debelak, Rudolf, and Ingrid Koller. 2019. “Testing the Local Independence Assumption of the Rasch Model with Q3-Based Nonparametric Model Tests.”Applied Psychological Measurement 44. https://doi.org/10.1177/0146621619835501.
Fasiolo, Matteo, Nedellec, Rapha"el, Goude, Yannig, Wood, and Simon N. 2020. “Scalable Visualisation Methods for Modern Generalized Additive Models.”Journal of the Royal Statistical Society (B) 29 (1): 78–86.
Johansson, Magnus, Marit Preuter, Simon Karlsson, Marie-Louise Möllerberg, Hanna Svensson, and Jeanette Melin. 2023. “Valid and Reliable? Basic and Expanded Recommendations for Psychometric Reporting and Quality Assessment.”https://doi.org/10.31219/osf.io/3htzc.
Kines, Pete, Jorma Lappalainen, Kim Lyngby Mikkelsen, Espen Olsen, Anders Pousette, Jorunn Tharaldsen, Kristinn Tómasson, and Marianne Törner. 2011. “Nordic Safety Climate Questionnaire (NOSACQ-50): A New Tool for Diagnosing Occupational Safety Climate.”International Journal of Industrial Ergonomics 41 (6): 634–46. https://doi.org/10.1016/j.ergon.2011.08.004.
Koller, Ingrid, Marco Maier, and Reinhold Hatzinger. 2015. “An Empirical Power Analysis of Quasi-Exact Tests for the Rasch Model: Measurement Invariance in Small Samples.”Methodology 11. https://doi.org/10.1027/1614-2241/a000090.
Komboz, Basil, Achim Zeileis, and Carolin Strobl. 2018. “Tree-Based Global Model Tests for Polytomous Rasch Models.”Educational and Psychological Measurement 78 (1): 128–66. https://doi.org/10.1177/0013164416664394.
Kosmidis, Ioannis, and David Firth. 2021. “Jeffreys-Prior Penalty, Finiteness and Shrinkage in Binomial-Response Generalized Linear Models.”Biometirka 108: 71–82. https://doi.org/10.1093/biomet/asaa052.
Kosmidis, Ioannis, Euloge Clovis Kenne Pagui, and Nicola Sartori. 2020. “Mean and Median Bias Reduction in Generalized Linear Models.”Statistics and Computing 30: 43–59. https://doi.org/10.1007/s11222-019-09860-6.
Lüdecke, Daniel, Mattan S. Ben-Shachar, Indrajeet Patil, and Dominique Makowski. 2020. “Extracting, Computing and Exploring the Parameters of Statistical Models Using R.”Journal of Open Source Software 5 (53): 2445. https://doi.org/10.21105/joss.02445.
Mair, Patrick, and Reinhold Hatzinger. 2007a. “CML Based Estimation of Extended Rasch Models with the eRm Package in r.”Psychology Science 49. https://doi.org/10.18637/jss.v020.i09.
———. 2007b. “Extended Rasch Modeling: The eRm Package for the Application of IRT Models in r.”Journal of Statistical Software 20. https://doi.org/10.18637/jss.v020.i09.
Preuter, Marit, Magnus Johansson, and Tomas Bokström. 2022. Strukturer och indikatorer för uppföljning av föräldraskapsstöd. RISE rapport 2022:70. RISE Research Institutes of Sweden. http://urn.kb.se/resolve?urn=urn:nbn:se:ri:diva-59978.
Qiu, Yixuan, and authors/contributors of the included software. See file AUTHORS for details. 2024. showtext: Using Fonts More Easily in r Graphs. https://CRAN.R-project.org/package=showtext.
R Core Team. 2024. R: A Language and Environment for Statistical Computing. Vienna, Austria: R Foundation for Statistical Computing. https://www.R-project.org/.
Rosseel, Yves. 2012. “lavaan: An R Package for Structural Equation Modeling.”Journal of Statistical Software 48 (2): 1–36. https://doi.org/10.18637/jss.v048.i02.
Rusch, Thomas, Marco Maier, and Reinhold Hatzinger. 2013. “Linear Logistic Models with Relaxed Assumptions in r.” In Algorithms from and for Nature and Life, edited by Berthold Lausen, Dirk van den Poel, and Alfred Ultsch. Studies in Classification, Data Analysis, and Knowledge Organization. New York: Springer. https://doi.org/10.1007/978-3-319-00035-0_34.
Strobl, Carolin, Julia Kopf, and Achim Zeileis. 2015. “Rasch Trees: A New Method for Detecting Differential Item Functioning in the Rasch Model.”Psychometrika 80 (2): 289–316. https://doi.org/10.1007/s11336-013-9388-3.
Strobl, Carolin, Florian Wickelmaier, and Achim Zeileis. 2011. “Accounting for Individual Differences in Bradley-Terry Models by Means of Recursive Partitioning.”Journal of Educational and Behavioral Statistics 36 (2): 135–53. https://doi.org/10.3102/1076998609359791.
Thériault, Rémi. 2023. “lavaanExtra: Convenience Functions for Lavaan.”Journal of Open Source Software 8 (90): 5701. https://doi.org/10.21105/joss.05701.
Trepte, Sabine, and Markus Verbeet, eds. 2010. Allgemeinbildung in Deutschland – Erkenntnisse Aus Dem SPIEGELStudentenpisa-Test. Wiesbaden: VS Verlag.
Wickelmaier, Florian, and Achim Zeileis. 2018. “Using Recursive Partitioning to Account for Parameter Heterogeneity in Multinomial Processing Tree Models.”Behavior Research Methods 50 (3): 1217–33. https://doi.org/10.3758/s13428-017-0937-z.
Wickham, Hadley. 2007. “Reshaping Data with the Reshape Package.”Journal of Statistical Software 21 (12). https://www.jstatsoft.org/v21/i12/.
Wickham, Hadley, Mara Averick, Jennifer Bryan, Winston Chang, Lucy D’Agostino McGowan, Romain François, Garrett Grolemund, et al. 2019. “Welcome to the tidyverse.”Journal of Open Source Software 4 (43): 1686. https://doi.org/10.21105/joss.01686.
William Revelle. 2024. psych: Procedures for Psychological, Psychometric, and Personality Research. Evanston, Illinois: Northwestern University. https://CRAN.R-project.org/package=psych.
Xie, Yihui. 2014. “knitr: A Comprehensive Tool for Reproducible Research in R.” In Implementing Reproducible Computational Research, edited by Victoria Stodden, Friedrich Leisch, and Roger D. Peng. Chapman; Hall/CRC.
———. 2015. Dynamic Documents with R and Knitr. 2nd ed. Boca Raton, Florida: Chapman; Hall/CRC. https://yihui.org/knitr/.
———. 2023. knitr: A General-Purpose Package for Dynamic Report Generation in r. https://yihui.org/knitr/.
Xie, Yihui, J. J. Allaire, and Garrett Grolemund. 2018. R Markdown: The Definitive Guide. Boca Raton, Florida: Chapman; Hall/CRC. https://bookdown.org/yihui/rmarkdown.
---title: "Prevent Säkerhetsvisaren 2.0"subtitle: "Psykometrisk analys med Rasch-metodik"title-block-banner: "#009ca6"title-block-banner-color: "#FFFFFF"author: name: Magnus Johansson affiliation: RISE Research Institutes of Sweden affiliation-url: https://www.ri.se/shic orcid: 0000-0003-1669-592Xdate: 2024-05-03date-format: isodoi: '10.5281/zenodo.11108748'format: html: toc: true toc-depth: 4 toc-title: "Table of contents" embed-resources: true standalone: true page-layout: full mainfont: 'Lato' monofont: 'Roboto Mono' code-overflow: wrap code-fold: true code-tools: true number-sections: true fig-dpi: 96 layout-align: left linestretch: 1.6 theme: - materia - custom.scss css: styles.css license: CC BYexecute: echo: true warning: false message: false cache: trueeditor_options: markdown: wrap: 72 chunk_output_type: consolebibliography: - references.bib - grateful-refs.bib---```{r}#| label: setup# one package below requires that you use devtools to install them manually:# first install devtools by# install.packages('devtools')library(RISEkbmRasch) # devtools::install_github("pgmj/RISEkbmRasch")library(grateful)library(ggrepel)library(car)library(kableExtra)library(readxl)library(tidyverse)library(eRm)library(mirt)library(psych)library(psychotree)library(matrixStats)library(reshape)library(knitr)library(patchwork)library(formattable) library(glue)library(haven)library(labelled)library(qualtRics)library(janitor)library(lavaanExtra)library(lavaan)library(lavaanPlot)library(parameters)library(marginaleffects)library(modelsummary)library(showtext)library(broom)source("theme_prevent.R")### optional libraries#library(TAM)#library(skimr)### some commands exist in multiple packages, here we define preferred ones that are frequently usedselect <- dplyr::selectcount <- dplyr::countrecode <- car::recoderename <- dplyr::renameannotate <- ggplot2::annotatesource("RISE_theme.R")``````{r}# import item informationdf <-read_spss("data/prevent_safety_itemlabels.sav")# get metadata into a separate dataframeitem <-lapply(df, function(x) attributes(x)$label)itemlabels_all <-data.frame(itemnr =names(df),item =unlist(item),row.names =NULL)itemlabels <- itemlabels_all %>%filter(str_detect(itemnr, 'q1|q2|q3|q4')) %>%separate_wider_delim(item, names =c(NA,"item"), delim =". - ")``````{r}# import data# qualtrics_token <- read.table("../.qualtrics_token", header = FALSE) %>% # pull(V1)# qualtrics_url <- "fra1.qualtrics.com"# # qualtrics_api_credentials(api_key = qualtrics_token, # base_url = qualtrics_url)# # q <- all_surveys()# mysurvey <- fetch_survey(surveyID = q$id[1],# verbose = FALSE) %>% # clean_names() %>% # filter(start_date > '2024-03-26') # enkätstart 27e mars 2024, så filtrera bort äldre svar.# # df <- mysurvey %>% # filter(start_date > '2024-03-26') %>% # select(starts_with("q"),age,gender,role,bransch,duration_in_seconds) %>% # rownames_to_column("id")# demogr_vars <-as.character(expression(age,gender,role,bransch))# # write_csv(df,paste0(Sys.Date(),"_prevent_safety.csv"))df <-read_csv("data/prevent_safety_data.csv")``````{r}# recode to numericsdf2 <- df %>%select(!q5a) %>%#select(!q5b) %>% #fritextsvar bortplockademutate(across(starts_with("q"), ~ car::recode(.x,"'Stämmer helt'=3;'Stämmer ganska väl'=2;'Stämmer ganska dåligt'=1;'Stämmer inte alls'=0", as.factor =FALSE)))```## Introduktion till analys### Kort om analysmetodRISE har tagit fram fem grundläggande psykometriska kriterier som har varit utgångspunkt för analysarbetet. En artikel som beskriver kriterierna finns fritt tillgänglig som preprint [@johansson] och innehåller både en enklare och mera fördjupad beskrivning av kriterierna.Nedan finns en förenklad beskrivning av de psykometriska kriterierna på svenska, som kommer från RISE rapport till MFoF om uppföljning av föräldraskapsstöd [@preuter2022]:> När enkäter konstrueras och utvärderas bedöms dess psykometriska egenskaper, ofta kopplade till begreppen reliabilitet och validitet. Förenklat kan man säga att reliabilitet beskriver hur väl något mäts (vilken precision mätverktyget har), medan validitet beskriver hur väl innehållet i frågorna och svarskategorierna fångar det man avser att mäta. Dock råder i allmänhet oklara definitioner av begreppen och kriterier för huruvida dessa mätegenskaper uppfylls eller inte. Det medför att även enkäter som i forskningsartiklar beskrivs som "validerade" eller att de har "god reliabilitet" inte nödvändigtvis uppfyller vad som kan anses vara grundläggande kriterier. En mera omfattande beskrivning av de grundläggande psykometriska kriterierna återfinns i Bilaga 3 (separat dokument). Nedan listas kriterierna. Var och en av dem kräver psykometrisk analys av insamlade data för att bedöma.>> Lista över grundläggande psykometriska kriterier:>> - Svarskategorierna fungerar som avsett> - Frågorna fungerar likadant för olika grupper (kön, ålder, etc)> - Unidimensionalitet (utan för starkt korrelerade residualer)> - Frågornas svårighetsgrad passar målgruppens egenskaper/förmågor> - Reliabilitet/mätosäkerheter över skalans omfång är adekvat, sett till användningsområdet> - Omvandlingstabell till intervallskala>> Kriterierna ovan är ställda för att säkerställa att det är lämpligt att använda summapoäng från en enkät/skala. Summapoängen bör i sin tur användas tillsammans med en omvandlingstabell till intervallskala innan några statistiska eller matematiska beräkningar görs. Tyvärr är det mycket vanligt att forskningsstudier enbart redovisar Cronbach's alpha som ett mått på reliabilitet och/eller kvalitet på en enkät. Det är dessvärre gravt otillräckligt för att bedöma mätegenskaper hos ett mätverktyg, eftersom Cronbach's alpha inte ger information om något av kriterierna ovan.## Svarsbortfall```{r}df2 %>%select(starts_with(c("q1","q2","q3","q4"))) %>%RImissing()df2 %>%select(starts_with(c("q1","q2","q3","q4"))) %>%RImissingP(n =20)```Det är många som har missing data rakt igenom. Detta kan bero på att länken är öppen och tillgänglig även för "bottar" på internet, samt de som enbart är intresserade av att titta på frågorna men ej besvara dem.Vi tittar på hur många/stor andel det rör sig om.```{r}df2 %>%select(starts_with(c("q1","q2","q3","q4"))) %>%mutate(Missing =rowSums(is.na(.))) %>%count(Missing) %>%rename(`Antal saknade svar`= Missing) %>%kbl_rise()# all_missing <- df2 %>% # select(starts_with(c("q1","q2","q3","q4"))) %>% # mutate(Missing = rowSums(is.na(.))) %>%# rownames_to_column("id") %>% # filter(Missing == 22) %>% # pull(id)# # df2 %>% # rownames_to_column("id") %>% # filter(id %in% all_missing) %>% # select(all_of(demogr_vars)) %>% # na.omit() %>% # kbl_rise()``````{r}df3 <- df2 %>%select(id,starts_with(c("q1","q2","q3","q4"))) %>%na.omit()df3b <- df2 %>%select(id,q6,starts_with(c("q1","q2","q3","q4"))) %>%na.omit()dif_variables <- df2 %>%select(id,all_of(demogr_vars))df_dif <-left_join(df3, dif_variables, by ="id")d <- df3 %>%select(starts_with(c("q1","q2","q3","q4"))) %>%# reverse score 2 itemsmutate(across(c(q4_4,q2_2), ~ car::recode(.x,"3=0;2=1;1=2;0=3")) )```## Demografiska data```{r}#| layout-ncol: 2RIdemographics(df_dif$age,"Ålder")RIdemographics(df_dif$gender,"Kön")RIdemographics(df_dif$role,"Roll")# bransch sorteraddf_dif %>%count(bransch) %>%mutate(Procent =round(n*100/sum(n),2)) %>%arrange(desc(Procent)) %>%rename(Bransch = bransch,Antal = n) %>%kbl_rise()```Vi har mycket låg representation av åldersgruppen 19-29.```{r}# create DIF-variablesdif_age <-factor(df_dif$age)# too few responses in other gender groups, need to recode to missingdif_gender <- df_dif %>%mutate(gender =recode(gender,"'Vill ej ange'=NA;'Annat'=NA", as.factor =TRUE)) %>%pull(gender)dif_role <-factor(df_dif$role)dif_bransch <-factor(df_dif$bransch)```## Analys steg 1### Q1 Ledningens engagemang```{r}df.delskala <- d %>%select(starts_with("q1"))```#### Deskriptiv statistik```{r}RIallresp(df.delskala)```#### Descriptives - item level```{r}#| column: marginRIlistItemsMargin(df.delskala, fontsize =12)```::: panel-tabset##### Tile plot```{r}RItileplot(df.delskala)```##### Stacked bars```{r}RIbarstack(df.delskala)```##### Barplots```{r}#| layout-ncol: 2RIbarplot(df.delskala)```:::### Q1 Rasch-analysThe eRm package, which uses Conditional Maximum Likelihood (CML)estimation, will be used primarily. For this analysis, the PartialCredit Model will be used.```{r}#| column: margin#| echo: falseRIlistItemsMargin(df.delskala, fontsize =13)```::: panel-tabset#### Item fit```{r}RIitemfitPCM2(df.delskala, 250, 32)```#### PCA```{r}#| tbl-cap: "PCA of Rasch model residuals"RIpcmPCA(df.delskala)```#### Residualkorrelationer```{r}RIresidcorr(df.delskala, cutoff =0.2)```#### 1st contrast loadings```{r}RIloadLoc(df.delskala)```#### Svarskategorier```{r}#| layout-ncol: 2RIitemCats(df.delskala)```#### Targeting```{r}#| fig-height: 5# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)```#### Item-hierarki```{r}#| fig-height: 5RIitemHierarchy(df.delskala)```#### DIF kön```{r}RIdifTable(df.delskala, dif_gender)```#### DIF ålder```{r}RIdifTable(df.delskala, dif_age)```#### DIF roll```{r}RIdifTable(df.delskala, dif_role)```#### DIF bransch```{r}RIdifTable(df.delskala, dif_bransch)```#### Person location & infit ZSTD```{r}RIpfit(df.delskala)```#### Reliabilitet```{r}RItif(df.delskala, cutoff =2.5)```:::Mycket låg reliabilitet, p.g.a. få items.### Q2 Säkert ledarskap```{r}df.delskala <- d %>%select(starts_with("q2"))```#### Deskriptiv statistik```{r}RIallresp(df.delskala)```#### Descriptives - item level```{r}#| column: marginRIlistItemsMargin(df.delskala, fontsize =12)```::: panel-tabset##### Tile plot```{r}RItileplot(df.delskala)```##### Stacked bars```{r}RIbarstack(df.delskala)```##### Barplots```{r}#| layout-ncol: 2RIbarplot(df.delskala)```:::### Q2 Rasch-analysThe eRm package, which uses Conditional Maximum Likelihood (CML)estimation, will be used primarily. For this analysis, the PartialCredit Model will be used.```{r}#| column: margin#| echo: falseRIlistItemsMargin(df.delskala, fontsize =13)```::: panel-tabset#### Item fit```{r}RIitemfitPCM2(df.delskala, 250, 32)```#### PCA```{r}#| tbl-cap: "PCA of Rasch model residuals"RIpcmPCA(df.delskala)```#### Residualkorrelationer```{r}RIresidcorr(df.delskala, cutoff =0.2)```#### 1st contrast loadings```{r}RIloadLoc(df.delskala)```#### Svarskategorier```{r}#| layout-ncol: 2RIitemCats(df.delskala)```#### Targeting```{r}#| fig-height: 5# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)```#### Item-hierarki```{r}#| fig-height: 5RIitemHierarchy(df.delskala)```#### DIF kön```{r}RIdifTable(df.delskala, dif_gender)```#### DIF ålder```{r}RIdifTable(df.delskala, dif_age)```#### DIF roll```{r}RIdifTable(df.delskala, dif_role)```#### DIF bransch```{r}RIdifTable(df.delskala, dif_bransch)```#### Person location & infit ZSTD```{r}RIpfit(df.delskala)```:::Item q2_2 "Min närmsta chef har stort fokus på att kritisera misstag."avviker ur konstruktet. Mycket hög item fit och avvikande laddning påförsta kontrastfaktorn.Residualkorrelation mellan q2_4 och q2_6- q2_4 Min närmsta chef påminner mig om att följa säkerhetsreglerna även i pressade situationer.- q2_6 Min närmsta chef involverar mig i att prata om säkra beteenden och hur vi ska agera för att en olycka inte skall inträffa.### Q3 Förutsättningar```{r}df.delskala <- d %>%select(starts_with("q3"))```#### Deskriptiv statistik```{r}RIallresp(df.delskala)```#### Descriptives - item level```{r}#| column: marginRIlistItemsMargin(df.delskala, fontsize =12)```::: panel-tabset##### Tile plot```{r}RItileplot(df.delskala)```##### Stacked bars```{r}RIbarstack(df.delskala)```##### Barplots```{r}#| layout-ncol: 2RIbarplot(df.delskala)```:::### Q3 Rasch-analysThe eRm package, which uses Conditional Maximum Likelihood (CML)estimation, will be used primarily. For this analysis, the PartialCredit Model will be used.```{r}#| column: margin#| echo: falseRIlistItemsMargin(df.delskala, fontsize =13)```::: panel-tabset#### Item fit```{r}RIitemfitPCM2(df.delskala, 250, 32)```#### PCA```{r}#| tbl-cap: "PCA of Rasch model residuals"RIpcmPCA(df.delskala)```#### Residualkorrelationer```{r}RIresidcorr(df.delskala, cutoff =0.2)```#### 1st contrast loadings```{r}RIloadLoc(df.delskala)```#### Svarskategorier```{r}#| layout-ncol: 2RIitemCats(df.delskala)```#### Targeting```{r}#| fig-height: 5# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)```#### Item-hierarki```{r}#| fig-height: 5RIitemHierarchy(df.delskala)```#### DIF kön```{r}RIdifTable(df.delskala, dif_gender)```#### DIF ålder```{r}RIdifTable(df.delskala, dif_age)```#### DIF roll```{r}RIdifTable(df.delskala, dif_role)```#### DIF bransch```{r}RIdifTable(df.delskala, dif_bransch)```#### Person location & infit ZSTD```{r}RIpfit(df.delskala)```:::q3_3 har låg item fit, vilket är väntat med när ett generellt item kombineras med mera specifika items som mäter aspekter av samma sak. I övrigt ser allt ok ut, möjligen undantaget DIF för roll.### Q4 Säkert medarbetarskap```{r}df.delskala <- d %>%select(starts_with("q4"))```#### Deskriptiv statistik```{r}RIallresp(df.delskala)```#### Descriptives - item level```{r}#| column: marginRIlistItemsMargin(df.delskala, fontsize =12)```::: panel-tabset##### Tile plot```{r}RItileplot(df.delskala)```##### Stacked bars```{r}RIbarstack(df.delskala)```##### Barplots```{r}#| layout-ncol: 2RIbarplot(df.delskala)```:::### Q4 Rasch-analysThe eRm package, which uses Conditional Maximum Likelihood (CML)estimation, will be used primarily. For this analysis, the PartialCredit Model will be used.```{r}#| column: margin#| echo: falseRIlistItemsMargin(df.delskala, fontsize =13)```::: panel-tabset#### Item fit```{r}RIitemfitPCM2(df.delskala, 250, 32)```#### PCA```{r}#| tbl-cap: "PCA of Rasch model residuals"RIpcmPCA(df.delskala)```#### Residualkorrelationer```{r}RIresidcorr(df.delskala, cutoff =0.2)```#### 1st contrast loadings```{r}RIloadLoc(df.delskala)```#### Svarskategorier```{r}#| layout-ncol: 2RIitemCats(df.delskala)```#### Targeting```{r}#| fig-height: 5# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)```#### Item-hierarki```{r}#| fig-height: 5RIitemHierarchy(df.delskala)```#### DIF kön```{r}RIdifTable(df.delskala, dif_gender)```#### DIF ålder```{r}RIdifTable(df.delskala, dif_age)```#### DIF roll```{r}RIdifTable(df.delskala, dif_role)```#### DIF bransch```{r}RIdifTable(df.delskala, dif_bransch)```#### Person location & infit ZSTD```{r}RIpfit(df.delskala)```:::Item q4_4 avviker med hög item fit och laddning på förstaresidualkontrasten. Passar inte in i konstruktet.Residualkorrelation mellan items q4_5 och q4_6.- q4_5 Jag kan påpeka brister i säkerheten utan rädsla för negativa konsekvenser.- q4_6 Vi som arbetar här tar varandras synpunkter och förslag rörande säkerhet på allvar.q4_6 har låg item fit och bör tas bort.### NOSACQ-frågorna```{r}nosacq5 <-c("q1_1","q1_2","q2_1","q3_1","q4_1")``````{r}df.delskala <- d %>%select(all_of(nosacq5))``````{r}#| column: margin#| echo: falseRIlistItemsMargin(df.delskala, fontsize =13)```::: panel-tabset#### Item fit```{r}RIitemfitPCM2(df.delskala, 250, 32)```#### PCA```{r}#| tbl-cap: "PCA of Rasch model residuals"RIpcmPCA(df.delskala)```#### Residualkorrelationer```{r}RIresidcorr(df.delskala, cutoff =0.2)```#### 1st contrast loadings```{r}RIloadLoc(df.delskala)```#### Svarskategorier```{r}#| layout-ncol: 2RIitemCats(df.delskala)```#### Targeting```{r}#| fig-height: 5# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)```#### Item-hierarki```{r}#| fig-height: 5RIitemHierarchy(df.delskala)```#### DIF kön```{r}RIdifTable(df.delskala, dif_gender)```#### DIF ålder```{r}RIdifTable(df.delskala, dif_age)```#### DIF roll```{r}RIdifTable(df.delskala, dif_role)```#### DIF bransch```{r}RIdifTable(df.delskala, dif_bransch)```#### Person location & infit ZSTD```{r}RIpfit(df.delskala)```#### Reliabilitet```{r}RItif(df.delskala, cutoff =2)```:::Frågorna fungerar tillsammans, dock med låg reliabilitet och något låg item fit för två items.I en norsk forskningsartikel av Ajslev och kollegor [-@ajslev2017] används fem frågor från NOSACQ-50 [@kines_nordic_2011] som återfinns i den danska arbetsmiljöundersökningen NRCWE Arbejdsmiljø og Helbred 2012. Det verkar dock inte som att dessa fem items är samma som de fem som återfinns i Prevents enkät.Det man gör i artikeln är att dikotomisera de fem frågorna, så de tvånegativa/positiva svarskategorierna slås samman, och så räknar man"antalet arbetsmiljöproblem" på en skala 0-5. Sedan används den variabeln för att undersöka samband med självrapporterade olyckor. Vårt dataset innehåller också en självrapporterad variabel gällande olycka, och vi återkommer till analys av samband längre fram i detta dokument.```{r}thetas_nosacq <-RIestThetas(df.delskala)```### Explorativ analysÄven om vi har hypoteser om vilka items som ska hänga samman i separataområden finns ett intresse av att undersöka eventuella korsladdningaroch annat.```{r}# Define latent variableslatent <-list(f1 =names(d))# Write the model, and check itefa_0 <-write_lavaan(latent = latent)# one-factor modelf1 <-'efa("efa")*f1 =~ q1_1 + q1_2 + q1_3 + q2_1 + q2_2 + q2_3 + q2_4 + q2_5 + q2_6 + q3_1 + q3_2 + q3_3 + q3_4 + q3_5 + q3_6 + q3_7 + q4_1 + q4_2 + q4_3 + q4_4 + q4_5 + q4_6'# two-factorf2 <-'efa("efa")*f1 + efa("efa")*f2 =~ q1_1 + q1_2 + q1_3 + q2_1 + q2_2 + q2_3 + q2_4 + q2_5 + q2_6 + q3_1 + q3_2 + q3_3 + q3_4 + q3_5 + q3_6 + q3_7 + q4_1 + q4_2 + q4_3 + q4_4 + q4_5 + q4_6'f3 <-'efa("efa")*f1 + efa("efa")*f2 + efa("efa")*f3 =~ q1_1 + q1_2 + q1_3 + q2_1 + q2_2 + q2_3 + q2_4 + q2_5 + q2_6 + q3_1 + q3_2 + q3_3 + q3_4 + q3_5 + q3_6 + q3_7 + q4_1 + q4_2 + q4_3 + q4_4 + q4_5 + q4_6'f4 <-'efa("efa")*f1 + efa("efa")*f2 + efa("efa")*f3 +efa("efa")*f4 =~ q1_1 + q1_2 + q1_3 + q2_1 + q2_2 + q2_3 + q2_4 + q2_5 + q2_6 + q3_1 + q3_2 + q3_3 + q3_4 + q3_5 + q3_6 + q3_7 + q4_1 + q4_2 + q4_3 + q4_4 + q4_5 + q4_6'f5 <-'efa("efa")*f1 + efa("efa")*f2 + efa("efa")*f3 +efa("efa")*f4 +efa("efa")*f5 =~ q1_1 + q1_2 + q1_3 + q2_1 + q2_2 + q2_3 + q2_4 + q2_5 + q2_6 + q3_1 + q3_2 + q3_3 + q3_4 + q3_5 + q3_6 + q3_7 + q4_1 + q4_2 + q4_3 + q4_4 + q4_5 + q4_6'efa_f1 <-cfa(model = f1,data = d,rotation ="oblimin",estimator ="WLSMV",ordered =TRUE)efa_f2 <-cfa(model = f2,data = d,rotation ="oblimin",estimator ="WLSMV",ordered =TRUE)efa_f3 <-cfa(model = f3,data = d,rotation ="oblimin",estimator ="WLSMV",ordered =TRUE)efa_f4 <-cfa(model = f4,data = d,rotation ="oblimin",estimator ="WLSMV",ordered =TRUE)efa_f5 <-cfa(model = f5,data = d,rotation ="oblimin",estimator ="WLSMV",ordered =TRUE)```#### EFA model fit```{r}# define fit metrics of interestfit_metrics_robust <-c("chisq.scaled", "df", "pvalue.scaled", "cfi.robust", "tli.robust", "rmsea.robust", "rmsea.ci.lower.robust","rmsea.ci.upper.robust","srmr")rbind(fitmeasures(efa_f1, fit_metrics_robust),fitmeasures(efa_f2, fit_metrics_robust),fitmeasures(efa_f3, fit_metrics_robust),fitmeasures(efa_f4, fit_metrics_robust),fitmeasures(efa_f5, fit_metrics_robust)) %>%# wrangledata.frame() %>%mutate(across(where(is.numeric),~round(.x, 3))) %>%add_column(Model =paste0("f",c(1:5)), .before ="chisq.scaled") %>%rename(Chi2 = chisq.scaled,p = pvalue.scaled,CFI = cfi.robust,TLI = tli.robust,RMSEA = rmsea.robust,CI_low = rmsea.ci.lower.robust,CI_high = rmsea.ci.upper.robust,SRMR = srmr) %>%kbl_rise()```#### EFA faktorladdningarEndast 4- och 5-faktormodellerna har acceptabla model fit-värden, så vitittar närmare på dem.```{r}inspect(efa_f4,what="std")$lambda %>%round(2) %>%as_tibble() %>%mutate(across(everything(), ~cell_spec(.x, color =case_when(.x >=0.4~"red", TRUE~"black")))) %>%add_column(Item =names(d), .before ='f1') %>%formattable()inspect(efa_f5,what="std")$lambda %>%round(2) %>%as_tibble() %>%mutate(across(everything(), ~cell_spec(.x, color =case_when(.x >=0.4~"red", TRUE~"black")))) %>%add_column(Item =names(d), .before ='f1') %>%formattable()```### CFAVi gör en konfirmatorisk faktoranalys för att kunna titta påmodification indices, korsladdningar och residualkorrelationer i enmultidimensionell modell.```{r}# Define latent variableslatent_cfa <-list(ledningen =c("q1_1","q1_2","q1_3"),ledarskap =c("q2_1","q2_2","q2_3","q2_4", "q2_5", "q2_6"), föruts =c("q3_1","q3_2","q3_3","q3_4", "q3_5", "q3_6","q3_7"),medarb =paste0("q4_",c(1:6)) )# Write the model, and check itcfa_0 <-write_lavaan(latent = latent_cfa)cfa_out <-cfa(model = cfa_0,data = d,rotation ="oblimin",estimator ="WLSMV",ordered =TRUE)rbind(fitmeasures(cfa_out, fit_metrics_robust)) %>%# wrangledata.frame() %>%mutate(across(where(is.numeric),~round(.x, 3))) %>%#add_column(Model = paste0("f",c(1:5)), .before = "chisq.scaled") %>% rename(Chi2 = chisq.scaled,p = pvalue.scaled,CFI = cfi.robust,TLI = tli.robust,RMSEA = rmsea.robust,CI_low = rmsea.ci.lower.robust,CI_high = rmsea.ci.upper.robust,SRMR = srmr) %>%kbl_rise()```#### Modification indicesOrdnade efter storlek, störst först.```{r}#| column: margin#| echo: falseRIlistItemsMargin(d, fontsize =7)```#### KorsladdningarMed MI \> 10.```{r}modificationIndices(cfa_out,standardized = T) %>%as.data.frame(row.names =NULL) %>%filter(mi >10, op =="=~") %>%arrange(desc(mi)) %>%mutate(across(where(is.numeric),~round(.x, 3))) %>%kbl_rise(fontsize =14, tbl_width =75)```#### Residualkorrelationer```{r}modificationIndices(cfa_out,standardized = T) %>%as.data.frame(row.names =NULL) %>%filter(mi >10, op =="~~") %>%arrange(desc(mi)) %>%mutate(across(where(is.numeric),~round(.x, 3))) %>%kbl_rise(fontsize =14, tbl_width =75)```### Rasch explorativVi provar att lägga in alla 22 items i en Rasch-modell.```{r}df.delskala <- d```The eRm package, which uses Conditional Maximum Likelihood (CML)estimation, will be used primarily. For this analysis, the PartialCredit Model will be used.```{r}#| column: margin#| echo: falseRIlistItemsMargin(df.delskala, fontsize =13)```::: panel-tabset#### Item fit```{r}RIitemfitPCM2(df.delskala, 250, 32)```#### PCA```{r}#| tbl-cap: "PCA of Rasch model residuals"RIpcmPCA(df.delskala)```#### Residualkorrelationer```{r}RIresidcorr(df.delskala, cutoff =0.2)```#### 1st contrast loadings```{r}RIloadLoc(df.delskala)```#### Targeting```{r}#| fig-height: 11# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)```#### Item-hierarki```{r}#| fig-height: 11RIitemHierarchy(df.delskala)```:::Vi tar bort q2_2 och q4_4, samt löser ut de residualkorrelationer som även tidigare setts genom att ta bort: q4_6, q2_6, q2_5.### Rasch expl 2```{r}rem_item <-c("q2_2", "q4_4", "q4_6", "q2_6", "q2_5")df.delskala <- d %>%select(!all_of(rem_item))``````{r}#| column: margin#| echo: falseRIlistItemsMargin(df.delskala, fontsize =13)```::: panel-tabset#### Item fit```{r}RIitemfitPCM2(df.delskala, 250, 32)```#### PCA```{r}#| tbl-cap: "PCA of Rasch model residuals"RIpcmPCA(df.delskala)```#### Residualkorrelationer```{r}RIresidcorr(df.delskala, cutoff =0.2)```#### 1st contrast loadings```{r}RIloadLoc(df.delskala)```#### Targeting```{r}#| fig-height: 11# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)```#### Item-hierarki```{r}#| fig-height: 11RIitemHierarchy(df.delskala)```:::Det är tydligt att det finns multidimensionalitet i data, även efter att ha tagit bort våra mest problematiska items. Detta framgår utifrån PCA av residualer samt residualkorrelationer. Således avbryter vi denna explorativa analys.## Kommentarer steg 1### GenerelltReverserade items (q4_4 och q2_2) funkar dåligt dimensionalitetsmässigt.- q2_2 Min närmsta chef har stort fokus på att kritisera misstag.- q4_4 Ibland tar vi genvägar i arbetet för att arbetsvardagen ska bli smidigare, även om det kan innebära ökad risk.Ev. titta närmare på:- DIF för roll gällande "Förutsättningar".- DIF för ålder gällande "Säkert Medarbetarskap".### Ledningens engagemangLåg reliabilitet p.g.a. få items. Låg item fit för två items.### Säkert ledarskapItem q2_2 "Min närmsta chef har stort fokus på att kritisera misstag."avviker ur konstruktet. Mycket hög item fit och avvikande laddning påförsta kontrastfaktorn.Residualkorrelation mellan q2_4 och q2_6- q2_4 Min närmsta chef påminner mig om att följa säkerhetsreglerna även i pressade situationer.- q2_6 Min närmsta chef involverar mig i att prata om säkra beteenden och hur vi ska agera för att en olycka inte skall inträffa.### Förutsättningarq3_3 har låg item fit, vilket är väntat med när ett generellt item kombineras med mera specifika items som mäter aspekter av samma sak. I övrigt ser allt ok ut, möjligen undantaget DIF för roll.q3_3 kan tas bort. q3_4-6 hanterarområdet bättre pga högre specificitet (tydligare avgränsning) ifrågeställningarna.### Säkert medarbetarskapItem q4_4 avviker med hög item fit och laddning på förstaresidualkontrasten. Passar inte in i konstruktet.Residualkorrelation mellan items q4_5 och q4_6.- q4_5 Jag kan påpeka brister i säkerheten utan rädsla för negativa konsekvenser.- q4_6 Vi som arbetar här tar varandras synpunkter och förslag rörande säkerhet på allvar.q4_6 har låg item fit och bör tas bort.### Utifrån EFA/CFA multidimensionell analysq2_1 och q3_7 hänger mer ihop med q1 (ledningen), q3_7 även med q2 -q2_1 Jag anser att ambitionen att minska antalet olyckor genomsyrar detdagliga arbetet. - q3_7 Jag upplever att risker åtgärdas när depåtalats.Residualkorrelation mellan q3_7 och q2_5: - q2_5 Min närmsta cheflyssnar och agerar när jag berättar om något som inte fungerar gällandesäkerheten.q2_2 funkar som nämnt inte bra, men noterar intressantresidualkorrelation med q4_5- q4_5 Jag kan påpeka brister i säkerheten utan rädsla för negativa konsekvenser.- q2_2 Min närmsta chef har stort fokus på att kritisera misstag.q4_5 korsladdar på q3 i 4-faktors CFA### Åtgärder att testa#### q2q2_2 tas bort, q2_1 flyttas till q1#### q3q3_3 tas bort pga redundans. q3_7 flyttas till q1#### q4q4_5 har residualkorrelation med q4_6, kan ev fungera bättre i q3 så viflyttar den dit.q4_4 tas bort## Analys steg 2### Q1 Ledningens engagemang- q2_1 flyttas till q1 - q3_7 flyttas till q1```{r}df.delskala <- d %>%select(starts_with("q1"),q2_1,q3_7)``````{r}#| column: margin#| echo: falseRIlistItemsMargin(df.delskala, fontsize =13)```::: panel-tabset#### Item fit```{r}RIitemfitPCM2(df.delskala, 250, 32)```#### PCA```{r}#| tbl-cap: "PCA of Rasch model residuals"RIpcmPCA(df.delskala)```#### Residualkorrelationer```{r}RIresidcorr(df.delskala, cutoff =0.2)```#### 1st contrast loadings```{r}RIloadLoc(df.delskala)```#### Svarskategorier```{r}#| layout-ncol: 2RIitemCats(df.delskala)```#### Targeting```{r}#| fig-height: 5# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)```#### Item-hierarki```{r}#| fig-height: 5RIitemHierarchy(df.delskala)```#### DIF kön```{r}RIdifTable(df.delskala, dif_gender)```#### DIF ålder```{r}RIdifTable(df.delskala, dif_age)```#### DIF roll```{r}RIdifTable(df.delskala, dif_role)```#### DIF bransch```{r}RIdifTable(df.delskala, dif_bransch)```#### Person location & infit ZSTD```{r}RIpfit(df.delskala)```#### Reliabilitet```{r}RItif(df.delskala, cutoff =2)```#### Itemparametrar```{r}RIitemparams(df.delskala)RIitemparams(df.delskala,output ="file",filename ="q1_params.csv")```#### Ordinal -> intervall```{r}RIscoreSE(df.delskala,score_range =c(-6,8))RIscoreSE(df.delskala,score_range =c(-6,8),output ="figure")```:::```{r}items_q1 <-names(df.delskala)thetas_q1 <-RIestThetas(df.delskala,theta_range =c(-6,8))```### Q2 Säkert ledarskap- q2_2 tas bort- q2_1 flyttas till q1```{r}df.delskala <- d %>%select(starts_with("q2")) %>%select(!c(q2_1,q2_2))``````{r}#| column: margin#| echo: falseRIlistItemsMargin(df.delskala, fontsize =13)```::: panel-tabset#### Item fit```{r}RIitemfitPCM2(df.delskala, 250, 32)```#### PCA```{r}#| tbl-cap: "PCA of Rasch model residuals"RIpcmPCA(df.delskala)```#### Residualkorrelationer```{r}RIresidcorr(df.delskala, cutoff =0.2)```#### 1st contrast loadings```{r}RIloadLoc(df.delskala)```#### Svarskategorier```{r}#| layout-ncol: 2RIitemCats(df.delskala)```#### Targeting```{r}#| fig-height: 5# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)```#### Item-hierarki```{r}#| fig-height: 5RIitemHierarchy(df.delskala)```#### DIF kön```{r}RIdifTable(df.delskala, dif_gender)```#### DIF ålder```{r}RIdifTable(df.delskala, dif_age)```#### DIF roll```{r}RIdifTable(df.delskala, dif_role)```#### DIF bransch```{r}RIdifTable(df.delskala, dif_bransch)```#### Person location & infit ZSTD```{r}RIpfit(df.delskala)```#### Reliabilitet```{r}RItif(df.delskala, cutoff =2)```#### Itemparametrar```{r}RIitemparams(df.delskala)RIitemparams(df.delskala,output ="file",filename ="q2_params.csv")```#### Ordinal -> intervall```{r}RIscoreSE(df.delskala,score_range =c(-6,8))RIscoreSE(df.delskala,score_range =c(-6,8), output ="figure")```:::```{r}items_q2 <-names(df.delskala)thetas_q2 <-RIestThetas(df.delskala,theta_range =c(-6,8))```### Q3 Förutsättningar- q3_3 tas bort pga redundans- q3_7 flyttas till q1```{r}df.delskala <- d %>%select(starts_with("q3"),q4_5) %>%select(!c(q3_3,q3_7))``````{r}#| column: margin#| echo: falseRIlistItemsMargin(df.delskala, fontsize =13)```::: panel-tabset#### Item fit```{r}RIitemfitPCM2(df.delskala, 250, 32)```#### PCA```{r}#| tbl-cap: "PCA of Rasch model residuals"RIpcmPCA(df.delskala)```#### Residualkorrelationer```{r}RIresidcorr(df.delskala, cutoff =0.2)```#### 1st contrast loadings```{r}RIloadLoc(df.delskala)```#### Svarskategorier```{r}#| layout-ncol: 2RIitemCats(df.delskala)```#### Targeting```{r}#| fig-height: 5# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)```#### Item-hierarki```{r}#| fig-height: 5RIitemHierarchy(df.delskala)```#### DIF kön```{r}RIdifTable(df.delskala, dif_gender)```#### DIF ålder```{r}RIdifTable(df.delskala, dif_age)```#### DIF roll```{r}RIdifTable(df.delskala, dif_role)```#### DIF bransch```{r}RIdifTable(df.delskala, dif_bransch)```#### Person location & infit ZSTD```{r}RIpfit(df.delskala)```#### Reliabilitet```{r}RItif(df.delskala, cutoff =2)```#### Itemparametrar```{r}RIitemparams(df.delskala)RIitemparams(df.delskala,output ="file",filename ="q3_params.csv")```#### Ordinal -> intervall```{r}RIscoreSE(df.delskala,score_range =c(-6,8))RIscoreSE(df.delskala,score_range =c(-6,8),output ="figure")```:::```{r}items_q3 <-names(df.delskala)thetas_q3 <-RIestThetas(df.delskala,theta_range =c(-6,8))```### Q4 Säkert medarbetarskapq4_5 har residualkorrelation med q4_6, kan ev fungera bättre i q3 så viflyttar den dit.q4_4 tas bort.```{r}df.delskala <- d %>%select(starts_with("q4")) %>%select(!c(q4_4,q4_5))``````{r}#| column: margin#| echo: falseRIlistItemsMargin(df.delskala, fontsize =13)```::: panel-tabset#### Item fit```{r}RIitemfitPCM2(df.delskala, 250, 32)```#### PCA```{r}#| tbl-cap: "PCA of Rasch model residuals"RIpcmPCA(df.delskala)```#### Residualkorrelationer```{r}RIresidcorr(df.delskala, cutoff =0.2)```#### 1st contrast loadings```{r}RIloadLoc(df.delskala)```#### Svarskategorier```{r}#| layout-ncol: 2RIitemCats(df.delskala)```#### Targeting```{r}#| fig-height: 5# increase fig-height above as needed, if you have many itemsRItargeting(df.delskala)```#### Item-hierarki```{r}#| fig-height: 5RIitemHierarchy(df.delskala)```#### DIF kön```{r}RIdifTable(df.delskala, dif_gender)```#### DIF ålder```{r}RIdifTable(df.delskala, dif_age)```#### DIF roll```{r}RIdifTable(df.delskala, dif_role)```#### DIF bransch```{r}RIdifTable(df.delskala, dif_bransch)```#### Person location & infit ZSTD```{r}RIpfit(df.delskala)```#### Reliabilitet```{r}RItif(df.delskala, cutoff =2)```#### Itemparametrar```{r}RIitemparams(df.delskala)RIitemparams(df.delskala,output ="file",filename ="q4_params.csv")```#### Ordinal -> intervall```{r}RIscoreSE(df.delskala,score_range =c(-6,8))RIscoreSE(df.delskala,score_range =c(-6,8),output ="figure")```:::```{r}items_q4 <-names(df.delskala)thetas_q4 <-RIestThetas(df.delskala,theta_range =c(-6,8))```## Summering delskalor```{r}data.frame(thetas_q1, thetas_q2, thetas_q3, thetas_q4, thetas_nosacq) %>%write_csv("thetas.csv")df_thetas <-read_csv("thetas.csv")```Här är items fördelade på delskalor.```{r}data.frame(delskala =c("Ledningens Engagemang","Säkert ledarskap","Förutsättningar","Säkert medarbetarskap"),items =c(paste(items_q1, collapse =", "),paste(items_q2, collapse =", "),paste(items_q3, collapse =", "),paste(items_q4, collapse =", ")),stringsAsFactors =FALSE) %>% knitr::kable()```Eftersom vi flyttat runt items en del dubbelkollar vi så det inte blivitnågon dubblett.```{r}# check for duplicatesduplicated(c(items_q1,items_q2,items_q3,items_q4))``````{r}# make a table similar to the one above, but add in itemlabels for item descriptionsitems_final_set <-data.frame(delskala =c(rep("Ledningens Engagemang", length(items_q1)),rep("Säkert ledarskap", length(items_q2)),rep("Förutsättningar", length(items_q3)),rep("Säkert medarbetarskap", length(items_q4)) ),itemnr =c(items_q1,items_q2,items_q3,items_q4),stringsAsFactors =FALSE) %>%left_join(itemlabels, by ="itemnr")items_final_set %>%kbl_rise() %>%collapse_rows(columns =1)#write_csv(items_final_set, "items_final_set.csv")```Av de 22 items som prövats i denna analys har 3 tagits bort:- q2_2 Min närmsta chef har stort fokus på att kritisera misstag.- q3_3 Jag upplever att jag har rätt förutsättningar för att kunna jobba säkert.- q4_4 Ibland tar vi genvägar i arbetet för att arbetsvardagen ska bli smidigare, även om det kan innebära ökad risk.Både q2_2 och q4_4 har tagits bort på grund av att de inte passar in,vilket delvis kan bero på att de är de enda negativt formuleradefrågorna (som därmed har reverserad svarsskala i analysen). Gällandeq3_3 hade den kunnat vara kvar, men delskalan fungerar tillräckligt brautan den, och den tillförde relativt lite information eftersom det är engenerell fråga om förutsättningar.### CFA nya delskalorVi gör en CFA på de nya delskalorna, och passar på att lägga till en"higher order" latent variabel utifrån de fyra delskalorna.```{r}# Define latent variableslatent_cfa2 <-list(ledningen = items_q1,ledarskap = items_q2, föruts = items_q3,medarb = items_q4, säkerhet =c("ledningen", "ledarskap", "föruts", "medarb"))# Write the model, and check itcfa_2 <-write_lavaan(latent = latent_cfa2)cfa_out2 <-cfa(model = cfa_2,data = d,rotation ="oblimin",estimator ="WLSMV",ordered =TRUE)# define fit metrics of interestfit_metrics_robust <-c("chisq.scaled", "df", "pvalue.scaled", "cfi.robust", "tli.robust", "rmsea.robust", "rmsea.ci.lower.robust","rmsea.ci.upper.robust","srmr")rbind(fitmeasures(cfa_out2, fit_metrics_robust)) %>%# wrangledata.frame() %>%mutate(across(where(is.numeric),~round(.x, 3))) %>%#add_column(Model = paste0("f",c(1:5)), .before = "chisq.scaled") %>% rename(Chi2 = chisq.scaled,p = pvalue.scaled,CFI = cfi.robust,TLI = tli.robust,RMSEA = rmsea.robust,CI_low = rmsea.ci.lower.robust,CI_high = rmsea.ci.upper.robust,SRMR = srmr) %>%kbl_rise()```#### Faktorladdningar```{r}#| fig-width: 8lavaanPlot(model = cfa_out2, coefs = T, stand = T, covs = T,node_options =list(fontname ="Helvetica", fontsize =18), edge_options =list(color ="grey", fontsize =18),graph_options =list(rankdir ="TD"))```#### Modification indicesOrdnade efter storlek, störst först.```{r}#| column: margin#| echo: falsed %>%select(all_of(items_final_set$itemnr)) %>%RIlistItemsMargin(fontsize =7)```#### KorsladdningarMed MI \> 10.```{r}modificationIndices(cfa_out2,standardized = T) %>%as.data.frame(row.names =NULL) %>%filter(mi >10, op =="=~") %>%arrange(desc(mi)) %>%mutate(across(where(is.numeric),~round(.x, 3))) %>%kbl_rise(fontsize =14, tbl_width =75)```#### Residualkorrelationer```{r}modificationIndices(cfa_out2,standardized = T) %>%as.data.frame(row.names =NULL) %>%filter(mi >10, op =="~~") %>%arrange(desc(mi)) %>%mutate(across(where(is.numeric),~round(.x, 3))) %>%kbl_rise(fontsize =14, tbl_width =75)```### Korrelation mellan delskalorna```{r}# Define latent variableslatent_cfa3 <-list(ledningen = items_q1,ledarskap = items_q2, föruts = items_q3,medarb = items_q4#säkerhet = c("ledningen", "ledarskap", "föruts", "medarb"))# Write the model, and check itcfa_3 <-write_lavaan(latent = latent_cfa3)cfa_out3 <-cfa(model = cfa_3,data = d,rotation ="oblimin",estimator ="WLSMV",ordered =TRUE)cfa_summary3 <-summary(cfa_out3, standardized =TRUE)cfa_summary3[["pe"]] %>%as.data.frame() %>%filter(op =="~~",!str_detect(lhs,"q"),!lhs == rhs) %>%select(!c(exo,pvalue)) %>%mutate_if(is.numeric, ~round(., 3)) %>%kbl_rise()```### CFA övergripande säkerhetUtifrån estimerade mätvärden (thetas) från varje delskala.```{r}# Define latent variableslatent_cfa2nd <-list( säkerhet =names(df_thetas[c(1:4)]))# Write the model, and check itcfa_2nd <-write_lavaan(latent = latent_cfa2nd)cfa_out2nd <-cfa(model = cfa_2nd,data = df_thetas,rotation ="oblimin",estimator ="MLR")# define fit metrics of interestfit_metrics_robust <-c("chisq.scaled", "df", "pvalue.scaled", "cfi.robust", "tli.robust", "rmsea.robust", "rmsea.ci.lower.robust","rmsea.ci.upper.robust","srmr")rbind(fitmeasures(cfa_out2nd, fit_metrics_robust)) %>%# wrangledata.frame() %>%mutate(across(where(is.numeric),~round(.x, 3))) %>%#add_column(Model = paste0("f",c(1:5)), .before = "chisq.scaled") %>% rename(Chi2 = chisq.scaled,p = pvalue.scaled,CFI = cfi.robust,TLI = tli.robust,RMSEA = rmsea.robust,CI_low = rmsea.ci.lower.robust,CI_high = rmsea.ci.upper.robust,SRMR = srmr) %>%kbl_rise()``````{r}lavaanPlot(model = cfa_out2nd, coefs = T, stand = T, covs = T,node_options =list(fontname ="Helvetica", fontsize =18), edge_options =list(color ="grey", fontsize =18),graph_options =list(rankdir ="TD"))```## Meta-frågor om enkäten```{r}itemlabels_all %>%filter(itemnr %in%c("q5a","q5b")) %>%kbl_rise()```### Kvantitativ fråga```{r}#| fig-width: 8#| fig-height: 6# svarskategorier <- df %>%# select(q5a) %>%# pivot_longer(everything()) %>%# na.omit() %>%# distinct(value) %>%# pull(value)total_n <- df %>%select(q5a) %>%na.omit() %>%nrow()q5a_long <- df %>%select(q5a) %>%pivot_longer(everything()) %>%na.omit() %>%count(name, value) %>%# räkna hur många individer i varje svarskategorimutate(Procent = (100* n /sum(n))) %>%# räkna fram procent för varje svarskategorimutate(across(where(is.numeric), ~round(.x, 2))) %>%rename(Svarskategori = value, # byt namn på variabler inför skapande av figur. Fråga = name ) %>%left_join(itemlabels, by =join_by("Fråga"=="itemnr"))q5a_long %>%ggplot(aes(x = Svarskategori, y = Procent, fill = Svarskategori)) +scale_y_continuous(limits =c(0, 75), breaks =seq(0, 100, 10)) +# starta alltid y på 0scale_x_discrete(guide =guide_axis(n.dodge =1),labels =~str_wrap(as.character(.x), 18) ) +geom_col() +geom_text(aes(label =paste0("n = ", n)),color ="darkgrey",size =4,position =position_dodge(width =0.9),vjust =-0.4 ) +scale_fill_viridis_d(direction =-1) +theme_minimal() +theme_prevent() +theme(legend.position ="none") +labs(title =str_wrap("Tycker du att frågorna täcker in det som är viktigt för att beskriva de grundläggande aspekterna av säkerhetskulturen på en arbetsplats?", 59),subtitle =paste0("Antal svar totalt: ", total_n,". Andel positiva: ", q5a_long[1, 4] + q5a_long[2, 4], "%." ),caption =str_wrap("Staplarnas höjd anger andel (%) av respondenterna som svarat i respektive svarskategori. Siffran ovanför staplarna anger antalet respondenter som svarat i den kategorin.", 100) )```### Fritextkommentarer```{r}#| eval: falsefritext_n <- df %>%select(q5b) %>%na.omit() %>%nrow()```73 fritextsvar. Vi samlar dem i en CSV-fil. Dessa tillgängliggörs ej med annan data eftersom respondenter kan skriva vad som helst i detta fält.```{r}#| eval: falsewrite_csv(na.omit(df$q5b) %>%as.data.frame(), "fritext.csv")```## Varit med om olycka?```{r}#| fig-width: 9#| fig-height: 6total_n_q6 <- df %>%select(q6) %>%na.omit() %>%nrow()q6_long <- df %>%mutate(q6 =factor(q6,levels =c("Nej", "Ja, en gång", "Ja, två gånger", "Ja, tre gånger", "Ja, fyra gånger eller fler"),ordered =TRUE )) %>%select(q6) %>%pivot_longer(everything()) %>%na.omit() %>%count(name, value) %>%# räkna hur många individer i varje svarskategorimutate(Procent = (100* n /sum(n))) %>%# räkna fram procent för varje svarskategorimutate(across(where(is.numeric), ~round(.x, 2))) %>%rename(Svarskategori = value, # byt namn på variabler inför skapande av figur. Fråga = name ) %>%add_column(item ="Har du det senaste året varit med om en eller flera arbetsplatsolyckor som resulterat i mer än en dags frånvaro från arbetet?")q6_long %>%ggplot(aes(x = Svarskategori, y = Procent, fill = Svarskategori)) +scale_y_continuous(limits =c(0, 75), breaks =seq(0, 100, 10)) +# starta alltid y på 0geom_col() +geom_text(aes(label =paste0("n = ", n)),color ="darkgrey",size =4,position =position_dodge(width =0.9),vjust =-0.5 ) +scale_fill_viridis_d(direction =-1) +theme_minimal() +theme_prevent() +theme(legend.position ="none",panel.grid.major.x =element_blank(),panel.grid.minor.x =element_blank() ) +labs(title =str_wrap("Har du det senaste året varit med om en eller flera arbetsplatsolyckor som resulterat i mer än en dags frånvaro från arbetet?", 70),subtitle =paste0("Antal svar totalt: ", total_n_q6),caption =str_wrap("Staplarnas höjd anger andel (%) av respondenterna som svarat i respektive svarskategori. Siffran ovanför staplarna anger antalet respondenter (n) som svarat i den kategorin.", 100) )```### Strukturell ekvationsmodell```{r}d_sem <- df2 %>%select(starts_with(c("q1","q2","q3","q4")),q6,id) %>%mutate(q6dik =ifelse(q6 =="Nej",0,1)) %>%filter(id %in% df3$id)d_sem %>%count(q6,q6dik)d_sem <-cbind(d_sem,df_thetas)nosacq5 <-c("q1_1","q1_2","q2_1","q3_1","q4_1")final.items <-read_csv("items_final_set.csv")items_q1 <- final.items %>%filter(delskala =="Ledningens Engagemang") %>%pull(itemnr)items_q2 <- final.items %>%filter(delskala =="Säkert ledarskap") %>%pull(itemnr)items_q3 <- final.items %>%filter(delskala =="Förutsättningar") %>%pull(itemnr)items_q4 <- final.items %>%filter(delskala =="Säkert medarbetarskap") %>%pull(itemnr)# Define latent variableslatent_cfa2 <-list(ledningen = items_q1,ledarskap = items_q2, föruts = items_q3,medarb = items_q4, säkerhet =c("ledningen", "ledarskap", "föruts", "medarb"))# Define latent variableslatent_cfa3 <-list(ledningen = items_q1,ledarskap = items_q2, föruts = items_q3,medarb = items_q4)```#### Säkerhet som latent prediktor för olyckaMed övergripande "säkerhet" som latent variabel och prediktor för utfallet olycka (q6) dikotomiserat, d.v.s. där frekvensen av olyckor inte tas med, utan bara ja/nej. Vi har såpass få respondenter som angett att de varit med om olyckor att vi inte kan använda det mera graderade utfallet.```{r}regression1 <-list(q6dik ="säkerhet")# Write the model, and check itsem1 <-write_lavaan(latent = latent_cfa2,regression = regression1)sem1_out <-sem(model = sem1,data = d_sem,rotation ="oblimin",estimator ="WLSMV",ordered =TRUE)sem1_reg <-lavaan_reg(sem1_out)lavaan_reg(sem1_out, nice_table =TRUE, highlight =TRUE)exp(sem1_reg$b)#lavPredictY(sem1_out, xnames = "säkerhet", ynames = "q6dik")# https://stats.stackexchange.com/questions/596407/comparing-lavaansem-to-probit-regression-outputcoef(sem1_out)["q6dik|t1"]```#### De fyra delskalorna som separata latenta prediktorer```{r}regression2 <-list(q6dik =c("ledningen", "ledarskap", "föruts", "medarb"))# Write the model, and check itsem_2 <-write_lavaan(latent = latent_cfa3,regression = regression2)sem_out2 <-sem(model = sem_2,data = d_sem,rotation ="oblimin",estimator ="WLSMV",ordered =TRUE)#summary(sem2_out)#lavaan_reg(sem2_out)lavaan_reg(sem_out2, nice_table =TRUE, highlight =TRUE)```#### De fyra delskalorna som prediktorer med estimerade mätvärden.```{r}glm_all_theta <-glm(q6dik ~ thetas_q1 + thetas_q2 + thetas_q3 + thetas_q4, data = d_sem, family =binomial(link ="probit")) #probit is same as lavaan SEM usestidy(glm_all_theta)```#### NOSACQ-frågorna som latent prediktor```{r}regression3 <-list(q6dik ="nosacq")latent_cfa4 <-list(nosacq = nosacq5)# Write the model, and check itsem3 <-write_lavaan(latent = latent_cfa4,regression = regression3)sem3_out <-sem(model = sem3,data = d_sem,rotation ="oblimin",estimator ="WLSMV",ordered =TRUE)sem3_reg <-lavaan_reg(sem3_out)lavaan_reg(sem3_out, nice_table =TRUE, highlight =TRUE)exp(sem3_reg$b)```#### NOSACQ estimerade mätvärdenPlot av rådata med jitter på den dikotomiserade variabeln (bara 0 och 1 är möjliga svar).```{r}ggplot( d_sem,aes(x = thetas_nosacq, y = q6dik)) +geom_jitter(width =0.02, height =0.02) +geom_smooth(method ="loess") +scale_y_continuous(breaks =c(0, 1)) +geom_vline(xintercept =1.5, linetype ="dashed") +labs(x ="Estimerade mätvärden (theta) för de fem NOSACQ-frågorna",y ="Varit med om olycka (1) eller inte(0)", title ="Rådata" )```Ser ut som att vi når "botten" vid nosacq theta = 1.5?##### glm()Vi passar på att testa de två R-paketen som implementerar Firth's penalized logistic regression, som är allmänt rekommenderat vid mindre sampelstorlekar och/eller vid lågfrekventa utfall i data. Först kommer vanlig logistisk regression, sedan Firth's justerade metod två gånger.```{r}glm_nosacq_theta <-glm(q6dik ~ thetas_nosacq, data = d_sem, family =binomial(link ="logit"))tidy(glm_nosacq_theta)plot_predictions(glm_nosacq_theta, by ="thetas_nosacq") +#, transform = "exp")labs(x ="Estimerade mätvärden (theta) för de fem NOSACQ-frågorna",y ="Varit med om olycka (1) eller inte(0)", title ="Predicerade värden i statistisk modell", subtitle ="glm(q6dik ~ thetas_nosacq, data = d_sem, family = binomial(link = 'logit'))" )library(logistf)glm_nosacq_theta_p <-logistf(q6dik ~ thetas_nosacq, data = d_sem, family =binomial(link ="logit"))summary(glm_nosacq_theta_p)library(brglm2)glm_nosacq_theta_p2 <-glm(q6dik ~ thetas_nosacq, data = d_sem, family =binomial(link ="logit"), method ="brglmFit")tidy(glm_nosacq_theta_p2)plot_predictions(glm_nosacq_theta_p2, by ="thetas_nosacq") +#, transform = "exp")labs(x ="Estimerade mätvärden (theta) för de fem NOSACQ-frågorna",y ="Varit med om olycka (1) eller inte(0)", title ="Predicerade värden i statistisk modell", subtitle ="glm(q6dik ~ thetas_nosacq, data = d_sem, family = binomial(link = 'logit'), method = 'brglmFit')" )```Denna metod fångar inte "utplaningen" som sker efter x ~ 1.5, så vi behöver hitta en analysmetod som bättre passar data.##### gam()```{r}library(mgcViz) # https://mfasiolo.github.io/mgcViz/articles/mgcviz.htmlb <-gam(q6dik ~s(thetas_nosacq), data = d_sem, method ="REML")# b <- getViz(b)# plot( sm(b, 1) )# # lowest <- predict.gam(b) %>% min()predict.gam(b) %>%as.data.frame() %>%ggplot(aes(.)) +geom_histogram() +xlab("Predicted values")plot_predictions(b, condition ="thetas_nosacq") #transform = "exp")plot_predictions(b, condition ="thetas_nosacq", transform ="exp") +labs(y ="q6dik exponentiated")#plot_slopes(b, variables = "thetas_nosacq", condition = "thetas_nosacq")```Här är nosacq_theta = 2 "botten". Det ser också rimligt ut som gränsvärde utifrån targetingfiguren (sektion 4.11), och motsvarar att ha svarat nästa högsta svarsalternativet på alla fem frågorna.#### NOSACQ sum scores gam()```{r}d_sem <- d_sem %>%mutate(nosacq_sumscore =rowSums(across(all_of(nosacq5))))hist(d_sem$nosacq_sumscore, breaks =15)abline(v =mean(d_sem$nosacq_sumscore))b2 <-gam(q6dik ~s(nosacq_sumscore), data = d_sem, method ="REML")# b <- getViz(b)# plot( sm(b, 1) )# # lowest <- predict.gam(b) %>% min()predict.gam(b2) %>%as.data.frame() %>%ggplot(aes(.)) +geom_histogram() +xlab("Predicted values")plot_predictions(b2, condition ="nosacq_sumscore") +scale_x_continuous(breaks =seq(0,15,2)) #transform = "exp")plot_predictions(b2, condition ="nosacq_sumscore", transform ="exp") +labs(y ="q6dik exponentiated") +scale_x_continuous(breaks =seq(0,15,2))#plot_slopes(b2, variables = "nosacq_sumscore", condition = "nosacq_sumscore")```Sum score 10 = svarsalternativ 2 på alla fem frågorna. Men även 8-9 verkar ge goda utfall (1-2 frågor med svar "Stämmer ganska dåligt"). Allt detta med reservation för att vi har ett litet sampel.## Programvara som använts för analyserna```{r}pkgs <-cite_packages(cite.tidyverse =TRUE, output ="table",bib.file ="grateful-refs.bib",include.RStudio =TRUE,out.dir =getwd())formattable(pkgs, table.attr ='class=\"table table-striped\" style="font-size: 15px; font-family: Lato; width: 80%"')``````{r}sessionInfo()```## Referenser