library(foreign)library(readxl)library(RISEkbmRasch) # devtools::install_github("pgmj/RISEkbmRasch")library(grateful) # devtools::install_github("Pakillo/grateful")library(ggrepel)library(car)library(kableExtra)library(readxl)library(tidyverse)library(eRm)library(mirt)library(psych)library(ggplot2)library(psychotree)library(matrixStats)library(reshape)library(knitr)library(cowplot)library(formattable) library(glue)library(hexbin)library(skimr)### some commands exist in multiple packages, here we define preferred ones that are frequently usedselect <- dplyr::selectcount <- dplyr::countrecode <- car::recoderename <- dplyr::rename# file paths will need to have "../" added at the beginning to be able to render document# get itemlabelsitemlabels <-read_excel("../data/Itemlabels.xlsx") %>%filter(str_detect(itemnr, pattern ="abk|å")) %>%select(!Dimension)spssDatafil <-"../data/2023-04-26 Prevent OSA-enkat.sav"# read SurveyMonkey datadf <-read.spss(spssDatafil, to.data.frame =TRUE) %>%select(starts_with("q0006"), starts_with("q0009"),q0001,q0002,q0003,q0004) %>%rename(Kön = q0002, Ålder = q0001,Bransch = q0003,Hemarbete = q0004)# SPSS format provides itemlabels too, we can save them in a dataframespssLabels <- df %>%attr('variable.labels') %>%as.data.frame()dif.kön <- df$Köndif.ålder <- df$Ålderdif.bransch <- df$Branschdif.hemarbete <- df$Hemarbetedf <- df %>%select(starts_with("q0006"), starts_with("q0009"))names(df) <- itemlabels$itemnr
RIdemographics(dif.ålder,"Ålder") # kanske även fixa en figur?
Ålder
n
Percent
18-29
22
3.8
30-39
103
17.8
40-49
175
30.2
50-59
215
37.1
60+
64
11.1
Code
RIdemographics(dif.bransch,"Bransch")
Bransch
n
Percent
Kontorsarbete (oavsett bransch)
284
49.1
Industri
26
4.5
Hotell, restaurang, service
8
1.4
Handel
16
2.8
Skola, utbildning
67
11.6
Vård, omsorg
99
17.1
Byggverksamhet
7
1.2
Annat
71
12.3
Code
RIdemographics(dif.hemarbete,"Antal dagar med arbete hemifrån")
Antal dagar med arbete hemifrån
n
Percent
En dag
136
23.5
Två dagar
105
18.1
Tre dagar
35
6.0
Fyra dagar
10
1.7
Fem dagar
2
0.3
Jag arbetar aldrig eller sällan hemifrån
291
50.3
12.1.1 Svarsbortfall items
Vi filtrerar bort respondenter som har färre än två svar på frågorna i delskalan.
Code
# If you want to include participants with missing data, input the minimum number of items responses that a participant should have to be included in the analysis:min.responses <-2scale.items <- itemlabels$itemnr# Select the variables we will work with, and filter out respondents with a lot of missing datadf.omit.na <- df %>%filter(length(scale.items)-rowSums(is.na(.[scale.items])) >= min.responses)RImissing(df.omit.na, c("abk", "å"))
Vi har relativt få saknade svar, och tar därför bort respondenterna som inte har kompletta svar.
RIitemfitPCM2(df.omit.na, samplesize =250, nsamples =32, cpu =8)
OutfitMSQ
InfitMSQ
OutfitZSTD
InfitZSTD
abk1
0.663
0.679
-4.082
-3.995
abk2
0.751
0.773
-2.873
-2.69
abk3
1.404
1.304
3.414
2.81
abk4
0.795
0.81
-2.245
-2.483
abk5
1.231
1.165
2.026
1.944
abk6
1.205
1.196
2.065
2.044
å1
0.987
0.923
0.276
-0.793
å2
0.706
0.719
-3.958
-3.309
å3
0.676
0.683
-4.2
-4.14
å4
0.824
0.812
-2.171
-2.638
å5
1.163
1.107
1.791
1.388
Code
RIpcmPCA(na.omit(df.omit.na))
PCA of Rasch model residuals
Eigenvalues
1.98
1.88
1.26
1.21
1.08
Code
RIresidcorr(df.omit.na, cutoff =0.2)
abk1
abk2
abk3
abk4
abk5
abk6
å1
å2
å3
å4
å5
abk1
abk2
0.5
abk3
-0.19
-0.29
abk4
0.09
0.03
0.19
abk5
-0.1
-0.08
-0.1
-0.11
abk6
-0.14
-0.22
-0.02
0.04
-0.12
å1
-0.2
-0.15
-0.14
-0.24
-0.14
-0.26
å2
-0.09
0
-0.2
-0.25
-0.13
-0.24
0.12
å3
-0.04
-0.02
-0.17
-0.25
-0.08
-0.21
0.05
0.36
å4
-0.15
-0.22
-0.06
-0.08
-0.24
-0.04
-0.06
-0.04
-0.03
å5
-0.22
-0.18
-0.1
-0.15
-0.16
-0.02
0
-0.2
-0.25
0.07
Note:
Relative cut-off value (highlighted in red) is 0.11, which is 0.2 above the average correlation.
Code
RIloadLoc(df.omit.na)
Code
RIitemCats(df.omit.na, items ="all")
Code
# increase fig-height above as needed, if you have many itemsRItargeting(df.omit.na)
Code
RIitemHierarchy(df.omit.na)
Den initiala analysen som inkluderar samtliga items från områdena ‘arbetsbelastning och krav’ och ‘återhämtning’ visar att item abk1, abk3 och å3 visar låg item fit sett till rekommenderade tröskelvärden. Därtill visar å2 en relativt låg item fit, precis över det rekommenderade trsökelvärdet. Det finns även höga residualkorrelationer mellan abk1 och abk2, abk3 och abk4, samt å2 och å3. Item abk1, abk3 och å2 tas därför bort och analysen körs igen. Eftersom å2 kan tänkas vara ett relevant item i flera branscher än å3 tas å2 bort från fortsatt analys (det är inte möjligt att arbeta i en lugnare takt efter arbetsintensiva perioder i alla branscher). Vi slår också ihop svarsalternativ 1 och 2 för abk2, som visar oordnade trösklar.
Code
# create vector with eliminated itemsremoved_items <-c("abk1", "abk3", "å2")# select all items except those removeddf2 <- df.omit.na %>%select(!any_of(removed_items)) %>%mutate(abk2 =recode(abk2, "0=0;1=1;2=1;3=2;4=3;5=4") )
12.4 Rasch-analys 2
itemnr
item
abk2
Jag hinner med mina arbetsuppgifter inom min arbetstid.
abk4
Jag upplever att andras krav på mig är rimliga.
abk5
Jag kan få hjälp om min arbetsbelastning är för hög.
abk6
Mitt arbete är fritt från psykiskt påfrestande arbetsuppgifter.
å1
Jag kan använda raster till att koppla av från arbetet.
å3
Jag har tid för reflektion över hur jag har utfört arbetet.
å4
Jag har ork kvar för att göra andra saker efter arbetsdagens slut.
å5
Jag kan lägga tankar på arbetet åt sidan på min lediga tid.
RIitemfitPCM2(df2, samplesize =250, nsamples =32, cpu =8)
OutfitMSQ
InfitMSQ
OutfitZSTD
InfitZSTD
abk2
0.773
0.767
-2.741
-2.997
abk4
0.808
0.831
-2.24
-2.194
abk5
1.097
1.093
0.944
1.072
abk6
1.104
1.111
1.1
1.273
å1
0.932
0.889
-0.819
-1.347
å3
0.714
0.713
-3.466
-3.559
å4
0.777
0.767
-2.649
-2.833
å5
1.022
1.001
0.27
0.11
Code
RIpcmPCA(na.omit(df2))
PCA of Rasch model residuals
Eigenvalues
1.57
1.50
1.23
1.09
0.96
Code
RIresidcorr(df2, cutoff =0.2)
abk2
abk4
abk5
abk6
å1
å3
å4
å5
abk2
abk4
0.1
abk5
-0.08
-0.12
abk6
-0.18
0.02
-0.19
å1
-0.11
-0.24
-0.18
-0.32
å3
0.06
-0.2
-0.08
-0.23
0.07
å4
-0.17
-0.09
-0.3
-0.1
-0.09
-0.01
å5
-0.19
-0.19
-0.24
-0.11
-0.06
-0.28
0
Note:
Relative cut-off value (highlighted in red) is 0.074, which is 0.2 above the average correlation.
Code
RIloadLoc(df2)
Code
# increase fig-height above as needed, if you have many itemsRItargeting(df2)
Code
RIitemHierarchy(df2)
Analysens utfall ser bra ut. Abk4 och abk2 visar en residualkorrelation strax över det rekommenderade gränsvärdet, men eftersom den är marginell går vi vidare och undersöker DIF och reliabilitet.
12.4.0.1 DIF-analysis
En DIF-analys bör inte inkludera svarskategorier med för få svar. Därför har svarskategorier med färre än 50 svar antingen exkluderas eller slagits ihop med andra svarskategorier (se avsnittet om bakgrundsdata för exakt antal svar per ordinarie kategori). DIF-variablerna omkodades till att innehålla följande kategorier:
Kön: man, kvinna
Ålder: 30-39, 40-49, 50-59, 60+
Bransch: kontorsarbete, ej kontorsarbete
Hemarbete: aldrig eller sällan, en dag, minst två dagar
Koden nedan specificerar exakt hur omkodningen gick till.
Code
# Omkodning för köndif.kön <-recode(dif.kön,"'Annat'=NA;'Vill ej uppge'=NA")# Omkodning för ålderdif.ålder <-recode(dif.ålder,"'18-29'=NA")# Omkodning för branschdif.bransch <-recode(dif.bransch,"'Industri'='Ej kontorsarbete';'Hotell, restaurang, service'='Ej kontorsarbete';'Handel'='Ej kontorsarbete';'Skola, utbildning'='Ej kontorsarbete';'Vård, omsorg'='Ej kontorsarbete';'Byggverksamhet'='Ej kontorsarbete';'Annat'='Ej kontorsarbete'")#Omkodning för hemarbetedif.hemarbete <-recode(dif.hemarbete,"'Fem dagar'='Minst två dagar';'Fyra dagar'='Minst två dagar';'Tre dagar'='Minst två dagar';'Två dagar'='Minst två dagar'")