Author
Affiliation
Magnus Johansson
Published

February 8, 2023

10.1 Bakgrund

Vi har tagit data från 2020, eftersom två frågor tillkommit 2020.

Frågorna har delats in i tre tänkta områden, som markerats med bakgrundsfärg i tabellen med items längre ner:

  • eget bruk
  • debutålder
  • föräldrarna/familjen

Frågorna har stor variation i svarskategorierna, vilket beskrivs i PDF-filen med frågor, och även framgår om man klickar på vid denna sidas rubrik högst upp och tittar på källkoden till analysen där omkodning (“recode”) av svarskategorierna finns med tidigt i koden (innan denna text).

Exempel på vanliga typer av svarskategorier och deras omkodning:

  • ‘Nej, jag har aldrig rökt’=0;
  • ‘Nej, bara provat hur det smakar’=1;
  • ‘Nej, jag har rökt men slutat’=2;
  • ‘Ja, ibland men inte varje dag’=3;
  • ‘Ja, dagligen’=4;

och:

  • ‘Nej, ingen gång’=0;
  • ‘Ja, 1 gång’=1;
  • ‘Ja, 2-4 gånger’=2;
  • ‘Ja, 5-10 gånger’=3;
  • ‘Ja, 11-20 gånger’=4;
  • ‘Ja, 21-50 gånger’=5;
  • ‘Ja, mer än 50 gånger’=6;

Denna typ av frekvensskattningar med så många svarsalternativ brukar sällan ge psykometriskt meningsfull information, d.v.s. det är inte tillräckligt stor skillnad på de olika svarsalternativen för att var och en av kategorierna ska bidra med mera information om respondenten. Vi kommer med största sannolikhet behöva slå samman flera av dem för att kunna göra en rimlig analys.

För denna analys är målsättningen inte att undersöka möjligheten att ta fram ett eller flera indexvärden utifrån sammansättningar av items/frågor som sedan kan användas på samtliga deltagare. Detta beror på att de flesta deltagare har såpass liten användning av substanser eller ens har svarat på frågorna. Däremot vill vi se hur frågorna fungerar relativt varandra (item-hierarki) och om det skiljer sig mellan kön, årskurs och över tid.

Code
itemlabels %>% 
  kbl(booktabs = T, escape = F) %>%
      # bootstrap options are for HTML output
      kable_styling(bootstrap_options = c("striped", "hover"), 
                    position = "left",
                    full_width = F,
                    font_size = r.fontsize,
                    fixed_thead = T) %>% # when there is a long list in the table
      #  column_spec(c(2:3), color = "red") %>% 
      row_spec(1:9, bold = F, color = "black", background = "lightblue") %>% 
      row_spec(10:14, bold = F, color = "white", background = RISEprimGreen) %>%
      row_spec(15:19, bold = F, color = "white", background = RISEcompPurple) %>%
      column_spec(1, bold = T) %>% 
      kable_classic(html_font = "Lato")
itemnr item
F14 Röker du?
FNY12020 Röker du e-cigaretter?
F18 Snusar du?
F34 Hur ofta dricker du vid ett och samma tillfälle alkohol motsvarande minst 18cl sprit?
F41 Har du sniffat/boffat någon gång?
F47 Hur många gånger totalt har du använt hasch/marijuana?
F48 Hur många gånger totalt har du använt annan narkotika än hasch/marijuana?
f53 Har du det senaste läsåret varit i kontakt med någon hjälpinstans p.g.a alkohol eller droger?
F73 Hur mycket pengar har du spelat för de senaste 30 dagarna?
F16 Hur gammal var du första gången du rökte?
F20 Hur gammal var du första gången du snusade?
F37 Hur gammal var du första gången du kände dig berusad?
F44 Hur gammal var du första gången du sniffade/boffade?
F51 Hur gammal var du första gången du använde narkotika?
F17 Får du röka för dina föräldrar?
F21 Får du snusa för dina föräldrar?
f22 Använder någon i din familj tobak (röker eller snusar)?
F40 Får du dricka alkohol för dina föräldrar?
FNY22020 Får du satsa pengar på spel för dina föräldrar?

10.2 Bortfall i data

Eftersom ANDTS-frågorna har större bortfall i svar kommer vi inte helt filtrera bort respondenter med saknade svar.

Code
RIlistItemsMargin(df.omit.na, 11)
itemnr item
F14 Röker du?
FNY12020 Röker du e-cigaretter?
F18 Snusar du?
F34 Hur ofta dricker du vid ett och samma tillfälle alkohol motsvarande minst 18cl sprit?
F41 Har du sniffat/boffat någon gång?
F47 Hur många gånger totalt har du använt hasch/marijuana?
F48 Hur många gånger totalt har du använt annan narkotika än hasch/marijuana?
f53 Har du det senaste läsåret varit i kontakt med någon hjälpinstans p.g.a alkohol eller droger?
F73 Hur mycket pengar har du spelat för de senaste 30 dagarna?
F16 Hur gammal var du första gången du rökte?
F20 Hur gammal var du första gången du snusade?
F37 Hur gammal var du första gången du kände dig berusad?
F44 Hur gammal var du första gången du sniffade/boffade?
F51 Hur gammal var du första gången du använde narkotika?
F17 Får du röka för dina föräldrar?
F21 Får du snusa för dina föräldrar?
f22 Använder någon i din familj tobak (röker eller snusar)?
F40 Får du dricka alkohol för dina föräldrar?
FNY22020 Får du satsa pengar på spel för dina föräldrar?
Code
#---- Create a figure showing % of missing data for each item, based on the complete dataset----
df.omit.na %>%
  select(itemlabels$itemnr) %>% 
  
  t() %>% 
  as.data.frame() %>% 
  mutate(Missing = rowSums(is.na(.))) %>% 
  select(Missing) %>% 
  arrange(desc(Missing)) %>% 
  rownames_to_column(var = "Item") %>% 
  mutate(Percentage = Missing/nrow(df)*100) %>% 
  mutate(Item = factor(Item, levels = rev(Item))) %>%
  ggplot(aes(x = Item, y = Percentage)) +
  geom_col() +
  coord_flip() +
  ggtitle("Missing data per item") +
  xlab("Items") +
  ylab("Percentage of responses missing")

Efter att ha tagit bort respondenter med färre än 12 items besvarade ser bortfallet ut enligt nedan.

Code
#---- Filtering participants based on missing data----

# 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 <- 12

# Select the variables we will work with, and filter out respondents with a lot of missing data
df.omit.na <- df.omit.na %>% 
  filter(length(itemlabels$itemnr)-rowSums(is.na(.[itemlabels$itemnr])) >= min.responses)
# create DIF variables for gender and grade
dif.gender <- df.omit.na$Kön
df.omit.na$Kön <- NULL
dif.arskurs <- df.omit.na$ARSKURS
df.omit.na$ARSKURS <- NULL
dif.stadsdel <- df.omit.na$SkolSDO
df.omit.na$SkolSDO <- NULL

df.omit.na %>%
  select(itemlabels$itemnr) %>% 
  t() %>% 
  as.data.frame() %>% 
  mutate(Missing = rowSums(is.na(.))) %>% 
  select(Missing) %>% 
  arrange(desc(Missing)) %>% 
  rownames_to_column(var = "Item") %>% 
  mutate(Percentage = Missing/nrow(df)*100) %>% 
  mutate(Item = factor(Item, levels = rev(Item))) %>%
  ggplot(aes(x = Item, y = Percentage)) +
  geom_col() +
  coord_flip() +
  ggtitle("Missing data per item") +
  xlab("Items") +
  ylab("Percentage of responses missing")

Code
n2020 <- df %>% filter(ar == "2020") %>% nrow()

Vi har 3978 respondenter i data, av totalt 13065 respondenter för år 2020. Det innebär att samplet vi analyserar består av den delen som använder olika typer av substanser. Vi kan senare jämföra dem med de som filtrerats ut.

10.3 Deskriptiva data

10.3.1 Demografi

Code
RIdemographics(dif.gender, "Kön")
RIdemographics(dif.arskurs, "Årskurs")
#RIdemographics(dif.stadsdel, "Stadsdel")
Kön n Percent
Flicka 1828 47.6
Pojke 2009 52.4
Årskurs n Percent
Åk 9 1476 37.1
Gy 2 2502 62.9

10.3.2 Item-data

Vi tar bort items om debutålder från tile-plotten, eftersom de skulle göra övriga frågor svårlästa.

Code
df.omit.na %>% 
  select(!any_of(itemsANDTSdebut)) %>% 
  RItileplot()

Code
RIbarplot(df.omit.na)

Vi kan se att det är mycket få respondenter i en del kategorier, och flera olika strukturer på svarsfördelningar.

10.4 Eget bruk

Code
df.eget <- df.omit.na %>% 
  select(any_of(itemsANDTSegen))

10.4.1 Svarskategorier

Eftersom frekvensbaserade svarskategorier använts, som ofta har mindre psykometriskt meningsfulla skillnader mellan de högre kategorierna, behöver vi först titta på om de behöver slås samman.

Code
plot(mirt.rasch, type="trace")

Vi ser många problem här som behöver åtgärdas:

  • F14 - kategori 2 slås samman med kategori 3
  • FNY12020 - slår samman de tre högsta
  • F18 - slår samman 2+1 och 3+4
  • F34 - slår samman 1+2
  • F41 - tas bort - mycket få svar över 0
  • F47 - vi slår samman 3+4 och 5+6
  • F48 - dikotomiseras mellan 0 och övriga kategorier
  • F73 - vi slår samman mittenkategorierna 1-5, och låter 0 och 6 vara kvar.

Det innebär att boffning/sniffning tas bort.

10.4.2 Omkodning av svarskategorier

10.4.2.1 Tileplot

Code
df.eget$F14 <- recode(df.eget$F14,"3=2;4=3")
df.eget$FNY12020 <- recode(df.eget$FNY12020,"3:4=2")
df.eget$F18 <- recode(df.eget$F18,"2=1;3:4=2")
df.eget$F34 <- recode(df.eget$F34,"2=1;3=2;4=3;5=4")

df.eget$F41 <- NULL
df.eget$F47 <- recode(df.eget$F47,"4=3;5:6=4")
df.eget$F48 <- recode(df.eget$F48,"2=1;3:6=2")
df.eget$F73 <- recode(df.eget$F73,"2:5=1;6=2")

RItileplot(df.eget)

10.4.2.2 Analys av svarskategorier

Code
plot(mirt.rasch, type="trace")

F48 ser tveksam ut. Vi provar 1=0;2:3=1;4:6=2 i stället.

Code
df.eget$F48 <- recode(df.omit.na$F48,"1=0;2:3=1;4:6=2")
df.erm <- PCM(df.eget)
plotICC(df.erm, item.subset = "F48")

Ser bättre ut.

Code
RIlistItemsMargin(df.eget, fontsize = 11)
itemnr item
F14 Röker du?
FNY12020 Röker du e-cigaretter?
F18 Snusar du?
F34 Hur ofta dricker du vid ett och samma tillfälle alkohol motsvarande minst 18cl sprit?
F47 Hur många gånger totalt har du använt hasch/marijuana?
F48 Hur många gånger totalt har du använt annan narkotika än hasch/marijuana?
F73 Hur mycket pengar har du spelat för de senaste 30 dagarna?
Code
RIitemfitPCM2(df.eget, 500, 32, 8)
OutfitMSQ InfitMSQ OutfitZSTD InfitZSTD
F14 0.833 0.83 -0.525 -0.302
FNY12020 0.915 0.911 0.283 0.239
F18 0.909 0.89 -0.163 -0.138
F34 0.773 0.772 -0.829 -0.841
F47 0.722 0.725 -1.318 -1.425
F48 0.787 0.795 -0.493 -0.808
F73 1.436 1.433 0.447 -0.152
Code
RIpcmPCA(df.eget)
PCA of Rasch model residuals
Eigenvalues
1.56
1.40
1.28
1.14
1.03
Code
RIloadLoc(na.omit(df.eget))

Code
RIresidcorr(df.eget, cutoff = 0.2)
F14 FNY12020 F18 F34 F47 F48 F73
F14
FNY12020 -0.14
F18 -0.18 -0.04
F34 -0.13 -0.2 -0.08
F47 -0.1 -0.18 -0.12 -0.31
F48 -0.08 -0.11 -0.18 -0.2 0.14
F73 -0.23 -0.19 -0.08 -0.2 -0.23 -0.08
Note:
Relative cut-off value (highlighted in red) is 0.061, which is 0.2 above the average correlation.
Code
RItargeting(df.eget)

Code
RIitemHierarchy(df.eget)

Vi kan se att de två högsta svarskategorierna för F47 behöver slås samman, de är oordnade. Det är också tydligt att F73 har hög item fit och behöver tas bort.

Code
df.eget$F47 <- recode(df.eget$F47,"4=3")
df.eget$F73 <- NULL

10.5 Eget bruk 2

Code
RIlistItemsMargin(df.eget, fontsize = 11)
itemnr item
F14 Röker du?
FNY12020 Röker du e-cigaretter?
F18 Snusar du?
F34 Hur ofta dricker du vid ett och samma tillfälle alkohol motsvarande minst 18cl sprit?
F47 Hur många gånger totalt har du använt hasch/marijuana?
F48 Hur många gånger totalt har du använt annan narkotika än hasch/marijuana?
Code
RIitemfitPCM2(df.eget, 500, 32, 8)
OutfitMSQ InfitMSQ OutfitZSTD InfitZSTD
F14 0.847 0.849 -0.29 -0.483
FNY12020 0.91 0.908 -0.546 -0.755
F18 0.925 0.909 -0.779 -1.419
F34 0.754 0.748 -2.203 -1.834
F47 0.765 0.816 -2.365 -2.496
F48 0.823 0.83 -1.679 -2.207
Code
RIpcmPCA(df.eget)
PCA of Rasch model residuals
Eigenvalues
1.52
1.38
1.29
1.04
0.95
Code
RIloadLoc(na.omit(df.eget))

Code
RIresidcorr(df.eget, cutoff = 0.2)
F14 FNY12020 F18 F34 F47 F48
F14
FNY12020 -0.15
F18 -0.2 -0.05
F34 -0.16 -0.23 -0.1
F47 -0.09 -0.16 -0.09 -0.25
F48 -0.08 -0.11 -0.17 -0.21 0.09
Note:
Relative cut-off value (highlighted in red) is 0.069, which is 0.2 above the average correlation.
Code
RItargeting(df.eget)

Code
RIitemHierarchy(df.eget)

10.5.1 Summering av åtgärder för svarskategorier

Code
df.eget$F14 <- recode(df.eget$F14,"3=2;4=3")
df.eget$FNY12020 <- recode(df.eget$FNY12020,"3:4=2")
df.eget$F18 <- recode(df.eget$F18,"2=1;3:4=2")
df.eget$F34 <- recode(df.eget$F34,"2=1;3=2;4=3;5=4")

df.eget$F41 <- NULL
df.eget$F47 <- recode(df.eget$F47,"4=3;5:6=4")
df.eget$F47 <- recode(df.eget$F47,"4=3") # i praktiken 4:6=3 

df.eget$F73 <- recode(df.eget$F73,"2:5=1;6=2")
df.eget$F48 <- recode(df.omit.na$F48,"1=0;2:3=1;4:6=2")

10.6 Invarians/DIF

10.6.1 Kön

Code
RIlistItemsMargin(df.eget, 13)
itemnr item
F14 Röker du?
FNY12020 Röker du e-cigaretter?
F18 Snusar du?
F34 Hur ofta dricker du vid ett och samma tillfälle alkohol motsvarande minst 18cl sprit?
F47 Hur många gånger totalt har du använt hasch/marijuana?
F48 Hur många gånger totalt har du använt annan narkotika än hasch/marijuana?
Code
RIdifTable(df.eget, dif.gender)

Item 2 3 Mean location StDev MaxDiff
F14 0.933 1.764 1.348 0.587 0.831
FNY12020 -0.004 -0.056 -0.030 0.037 0.052
F18 -0.473 -1.078 -0.776 0.428 0.606
F34 -0.160 0.027 -0.066 0.133 0.188
F47 -1.324 -1.539 -1.431 0.152 0.215
F48 1.028 0.882 0.955 0.104 0.147
Code
RIdifFigure(df.eget, dif.gender)

Code
RIdifFigThresh(df.eget, dif.gender)

Det är röker och snusar som skiljer sig mellan könen. Figuren med itemtrösklar visar på mera detaljinformation.

10.6.2 Årskurs

Code
RIlistItemsMargin(df.eget, 13)
itemnr item
F14 Röker du?
FNY12020 Röker du e-cigaretter?
F18 Snusar du?
F34 Hur ofta dricker du vid ett och samma tillfälle alkohol motsvarande minst 18cl sprit?
F47 Hur många gånger totalt har du använt hasch/marijuana?
F48 Hur många gånger totalt har du använt annan narkotika än hasch/marijuana?
Code
RIdifTable(df.eget, dif.arskurs)

Item 2 3 Mean location StDev MaxDiff
F14 1.288 1.275 1.282 0.009 0.013
FNY12020 -0.428 0.188 -0.120 0.436 0.616
F18 -0.707 -0.698 -0.702 0.007 0.009
F34 -0.041 -0.077 -0.059 0.025 0.036
F47 -1.152 -1.604 -1.378 0.319 0.451
F48 1.039 0.915 0.977 0.088 0.125
Code
RIdifFigure(df.eget, dif.arskurs)

Code
RIdifFigThresh(df.eget, dif.arskurs)

FNY12020 går över gränsvärdet, medan F47 är mycket nära. Det verkar huvudsakligen vara den lägsta tröskeln som förändrats för F47.

10.6.3 Årtal

Här exkluderas FNY122020 eftersom den bara finns för 2020.

Code
final.items <- names(df.eget)
df.dif.years <- df %>% 
  select(any_of(final.items),ar) %>% 
  select(!FNY12020) %>% 
  na.omit()

dif.year <- df.dif.years$ar
df.dif.years$ar <- NULL

df.dif.years$F14 <- recode(df.dif.years$F14,"3=2;4=3")
df.dif.years$F18 <- recode(df.dif.years$F18,"2=1;3:4=2")
df.dif.years$F34 <- recode(df.dif.years$F34,"2=1;3=2;4=3;5=4")

df.dif.years$F41 <- NULL
df.dif.years$F47 <- recode(df.dif.years$F47,"4=3;5:6=4")
df.dif.years$F47 <- recode(df.dif.years$F47,"4=3") # i praktiken 4:6=3 

df.dif.years$F48 <- recode(df.dif.years$F48,"1=0;2:3=1;4:6=2")
Code
RIlistItemsMargin(df.dif.years, 13)
itemnr item
F14 Röker du?
F18 Snusar du?
F34 Hur ofta dricker du vid ett och samma tillfälle alkohol motsvarande minst 18cl sprit?
F47 Hur många gånger totalt har du använt hasch/marijuana?
F48 Hur många gånger totalt har du använt annan narkotika än hasch/marijuana?
Code
RIdifTable(df.dif.years, dif.year)

Item 4 5 7 8 12 13 14 15 Mean location StDev MaxDiff
F14 -0.820 -0.771 -0.759 -0.800 -0.753 -0.574 -0.363 -0.147 -0.623 0.246 0.673
F18 -0.143 0.027 0.145 0.251 0.372 0.342 0.227 -0.263 0.120 0.229 0.635
F34 -0.095 -0.227 -0.185 -0.030 0.088 0.084 0.213 0.333 0.023 0.194 0.560
F47 -0.639 -0.603 -0.808 -1.025 -1.176 -1.240 -1.469 -1.275 -1.030 0.317 0.866
F48 1.697 1.575 1.607 1.605 1.469 1.388 1.393 1.352 1.511 0.127 0.345
Code
RIdifFigure(df.dif.years, dif.year)

Code
RIdifFigTime(df.dif.years, dif.year)

Code
RIdifFigThresh(df.dif.years, dif.year)

Här sker en del intressanta förändringar över tid hos samtliga items.

10.7 Debutålder

Här är det förmodligen mest intressant att ta fram medelvärde, median, och spridningsmått, samt visualiseringar.

Det finns dock låga svar som är tvivelaktiga att ta med. När frågor om debutålder besvaras med exempelvis intervallet 0-4 år förefaller det osannolikt att svaret är uppriktigt.

Code
df.debut <- df.omit.na %>%
  select(any_of(itemsANDTSdebut))

10.7.1 Övergripande svarsfördelning

Tabellen nedan gäller samtliga fem items, enbart år 2020.

Code
df.debutAge %>% 
  filter(ar == 2020) %>% 
  select(all_of(itemsANDTSdebut)) %>% 
  RIallresp()
Response category Number of responses Percent
0 32 0.0
1 28 0.0
2 24 0.0
3 34 0.1
4 74 0.1
5 90 0.1
6 39 0.1
7 44 0.1
8 33 0.1
9 43 0.1
10 111 0.2
11 155 0.2
12 553 0.8
13 1190 1.8
14 2822 4.3
15 3567 5.5
16 2403 3.7
17 1269 1.9
18 211 0.3
19 35 0.1
20 3 0.0
NA 52565 80.5

Förslagsvis kodas alla svar under 9 års ålder som missing/NA innan andra beräkningar genomförs.

10.7.2 Omkodning av låga svar

Code
RIlistItemsMargin(df.debut, 13)
itemnr item
F16 Hur gammal var du första gången du rökte?
F20 Hur gammal var du första gången du snusade?
F37 Hur gammal var du första gången du kände dig berusad?
F44 Hur gammal var du första gången du sniffade/boffade?
F51 Hur gammal var du första gången du använde narkotika?
Code
df.debdist <- df.debutAge %>%
  mutate(across(itemsANDTSdebut, ~ recode(.x, "0:8=NA")))
df.debdist %>% 
  filter(ar == 2020) %>% 
  select(all_of(itemsANDTSdebut)) %>% 
  RItileplot()

10.7.3 Visualisering av debutålder

Code
df.debdist %>% 
  filter(ar == 2020) %>% 
  select(all_of(itemsANDTSdebut)) %>% 
  pivot_longer(everything()) %>%
  rename(Item = name,
         Ålder = value) %>% 
  ggplot(aes(x = Ålder, group = Item, fill = Item)) +
  geom_histogram(bins = 20,
                 position = "stack",
                 alpha = 0.9) +
  scale_fill_viridis_d() +
  scale_x_continuous(breaks = c(9:21))

Ovan finns alla svar samlade från både Åk 9 och Gy 2, och båda kön tillsammans.

Nedan finns svaren uppdelade på årskurs.

Code
df.debdist %>% 
  filter(ar == 2020) %>%
  filter(!ARSKURS == "<NA>") %>% 
  select(any_of(c(itemsANDTSdebut,"ARSKURS","ar"))) %>% 
  pivot_longer(itemsANDTSdebut) %>%
  rename(Item = name,
         Ålder = value,
         Årskurs = ARSKURS) %>%
  mutater = factor(ar)) %>% 
  ggplot(aes(x = Ålder, group = Item, fill = Item)) +
  geom_histogram(bins = 20,
                 position = "stack",
                 alpha = 0.9) +
  scale_fill_viridis_d() +
  scale_x_continuous(breaks = c(9:21)) +
  facet_wrap(~Årskurs)

Code
df.debdist %>% 
  filter(ar == 2020) %>%
  filter(!ARSKURS == "<NA>") %>% 
  filter(Kön %in% c("Pojke","Flicka")) %>% 
  select(any_of(c(itemsANDTSdebut,"ARSKURS","ar","Kön"))) %>% 
  pivot_longer(itemsANDTSdebut) %>%
  rename(Item = name,
         Ålder = value,
         Årskurs = ARSKURS) %>%
  mutater = factor(ar)) %>% 
  ggplot(aes(x = Ålder, group = Item, fill = Item)) +
  geom_histogram(bins = 20,
                 position = "stack",
                 alpha = 0.9) +
  scale_fill_viridis_d() +
  scale_x_continuous(breaks = c(9:21)) +
  facet_grid(Kön~Årskurs)

Nedan enbart åk2.

Code
df.debdist %>% 
  #filter(ar == 2020) %>%
  filter(ARSKURS == "Gy 2") %>% 
  filter(Kön %in% c("Pojke","Flicka")) %>% 
  select(any_of(c(itemsANDTSdebut,"ARSKURS","ar","Kön"))) %>% 
  pivot_longer(itemsANDTSdebut) %>%
  rename(Item = name,
         Ålder = value,
         Årskurs = ARSKURS) %>%
  mutater = factor(ar)) %>% 
  ggplot(aes(x = Ålder, group = Item, fill = Item)) +
  geom_histogram(bins = 20,
                 position = "stack",
                 alpha = 0.9) +
  scale_fill_viridis_d() +
  scale_x_continuous(breaks = c(9:21),
                     guide = guide_axis(n.dodge = 2)) +
  facet_grid(Kön~År)

10.7.4 Debutålder över tid, Gy 2 enbart

Eftersom frågan ställs till både åk 9 och årskurs 2 på gymnasiet verkar det mest relevant att enbart redovisa rapporteringen som görs när eleverna är äldre.

Code
df.debdist %>%
  #filter(ar == 2020) %>%
  filter(ARSKURS %in% c("Gy 2")) %>%
  filter(Kön %in% c("Pojke","Flicka")) %>%
  select(any_of(c(itemsANDTSdebut,"ARSKURS","ar","Kön"))) %>%
  pivot_longer(itemsANDTSdebut) %>%
  rename(Item = name,
         Ålder = value,
         Årskurs = ARSKURS) %>%
  filter(!is.na(Ålder)) %>% 
  mutater = factor(ar)) %>% #group_by(År,Årskurs) %>% count(Kön)
  group_by(År,Kön,Item) %>% 
  summarise(
    Medelvärde = mean(Ålder),
    SD = sd(Ålder)
  ) %>% 
  ggplot(aes(x = År, y = Medelvärde, group = Item, color = Item)) +
  geom_point(size = 2) +
  geom_line() +
  #geom_ribbon(aes(ymin = Medelvärde - SD, ymax = Medelvärde + SD, fill = Item, color = NULL), alpha = 0.1) +
  #scale_color_viridis_d(begin = 0.1) +
  scale_x_discrete(breaks = årtal,
                     guide = guide_axis(n.dodge = 2)) +
  labs(title = "Genomsnittslig debutålder per substans över tid") +
  facet_grid(~Kön)

10.7.4.1 Komplement med båda åk

Code
df.debdist %>%
  #filter(ar == 2020) %>%
  filter(ARSKURS %in% c("Åk 9","Gy 2")) %>%
  filter(Kön %in% c("Pojke","Flicka")) %>%
  select(any_of(c(itemsANDTSdebut,"ARSKURS","ar","Kön"))) %>%
  pivot_longer(itemsANDTSdebut) %>%
  rename(Item = name,
         Ålder = value,
         Årskurs = ARSKURS) %>%
  filter(!is.na(Ålder)) %>% 
  mutater = factor(ar)) %>% #group_by(År,Årskurs) %>% count(Kön)
  group_by(År,Kön,Årskurs,Item) %>% 
  summarise(
    Medelvärde = mean(Ålder),
    SD = sd(Ålder)
  ) %>% 
  ggplot(aes(x = År, y = Medelvärde, group = Item, color = Item)) +
  geom_point(size = 2) +
  geom_line() +
  #geom_ribbon(aes(ymin = Medelvärde - SD, ymax = Medelvärde + SD, fill = Item, color = NULL), alpha = 0.1) +
  #scale_color_viridis_d(begin = 0.1) +
  scale_x_discrete(breaks = årtal,
                     guide = guide_axis(n.dodge = 2)) +
  labs(title = "Genomsnittslig debutålder per substans över tid") +
  facet_grid(Årskurs~Kön)

10.7.5 Bortfall av svar

Code
RIlistItemsMargin(df.debut, 13)
itemnr item
F16 Hur gammal var du första gången du rökte?
F20 Hur gammal var du första gången du snusade?
F37 Hur gammal var du första gången du kände dig berusad?
F44 Hur gammal var du första gången du sniffade/boffade?
F51 Hur gammal var du första gången du använde narkotika?
Code
#---- Create a figure showing % of missing data for each item, based on the complete dataset----
df.debut %>%
  t() %>% 
  as.data.frame() %>% 
  mutate(Missing = rowSums(is.na(.))) %>% 
  select(Missing) %>% 
  arrange(desc(Missing)) %>% 
  rownames_to_column(var = "Item") %>% 
  mutate(Percentage = Missing/nrow(df)*100) %>% 
  mutate(Item = factor(Item, levels = rev(Item))) %>%
  ggplot(aes(x = Item, y = Percentage)) +
  geom_col() +
  coord_flip() +
  ggtitle("Missing data per item") +
  xlab("Items") +
  ylab("Percentage of responses missing")

Enbart de som besvarat åtminstone tre av de fem frågorna kan vara med i analysen.

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 <- 3

# Select the variables we will work with, and filter out respondents with a lot of missing data
df.deb2 <- df.debdist %>% 
  filter(length(itemsANDTSdebut)-rowSums(is.na(.[itemsANDTSdebut])) >= min.responses) %>% 
  select(any_of(itemsANDTSdebut))

Detta reducerar sampelstorleken från 3978 till 15283 respondenter.

10.7.6 Svarskategorier

Code
RIallresp(df.deb2)
Response category Number of responses Percent
9.0 486 0.6
10.0 1011 1.3
11.0 1774 2.3
12.0 4953 6.5
13.0 8670 11.3
13.5 1 0.0
14.0 12253 16.0
15.0 11593 15.2
16.0 7005 9.2
16.5 1 0.0
17.0 3624 4.7
18.0 491 0.6
19.0 136 0.2
20.0 4 0.0
NA 24413 31.9

Vi slår samman alla upp till 11 år i samma kategori, som betecknas med siffran 0, därefter blir 12 år = kategori 1, 13 år = 2, och så vidare upp till 18-20 år = 7.

Code
df.deb2 <- df.deb2 %>%
  mutate(across(everything(), ~ recode(.x, "1:11=0;12=1;13=2;13.5=2;14=3;15=4;16=5;16.5=6;17=6;18:20=7")))
Code
RItileplot(df.deb2)

Code
plot(mirt.rasch, type="trace")

Enbart item F16 (rökning) uppvisar ordnade svarskategorier. Vi går ändå vidare och tittar på andra parametrar innan några eventuella åtgärder görs.

Det är dock svårt att få modellen att konvergera, vilket också bekräftar att debutålder inte är meningsfullt att bygga något index av.

10.8 Explorativa indexberäkningar och visualisering

Smolkowski och kollegor (smolkowski2006?) skriver på sidan 241: “We created an index of substance use by summing the number of reported substances used in the last month: cigarettes, alcohol, marijuana, or any of the other drugs.”

Det ter sig lite märkligt att inte alls vikta substanserna, men vi kan prova ett liknande upplägg.

Vi har fem items som kan användas, som avser tobaksrökning, snus, alkohol, narkotika (inkl cannabis), samt e-cigaretter. Dock har den sistnämna enbart funnits sedan 2020, så den utelämnas tills vi har hittat ett sätt att se till att den inte förvränger jämförbarheten över tid. Det kan ev. vara lämpligt att på något vis integrera tobaksanvändning, oavsett form.

  • Fråga 37 (f36 i data), Hur många gånger har du druckit så mycket alkohol att du känt dig berusad under den senaste 4-veckorsperioden? Fördelningen av svaren är märklig, se histogram nedan
Code
hist(as.numeric(df$f36), col = RISEprimGreen)

Vi kodar om enligt: “4:12=3;13:31=NA”

Code
hist(df$f36r, col = RISEprimGreen)

Samma sak gäller frågan om narkotika-användning.

    1. Hur många gånger har du använt narkotika (cannabis eller annan narkotika) den senaste 4-veckors perioden?
Code
hist(as.numeric(df$F49), col = RISEprimGreen)

Omkodning: “4:12=3;13:100=NA”

Code
hist(df$F49r, col = RISEprimGreen)

Item F14 är inte formulerad enligt samma tydliga frekvensfråga som de två tidigare frågorna. Den har sedan tidigare kodats enligt nedan:

recode(df$F14,“‘Nej, jag har aldrig rökt’=0; ‘Nej, bara provat hur det smakar’=1; ‘Nej, jag har rökt men slutat’=2; ‘Ja, ibland men inte varje dag’=3; ‘Ja, dagligen’=4; ‘’=NA”, as.factor = F)

Och inför test av index kodas den “0:2=0;3=1;4=2”

Code
hist(df$F14r, col = RISEprimGreen)

Samma gäller FNY12020 (e-cigaretter)

recode(df$FNY12020,“‘Nej, jag har aldrig rökt e-cigaretter’=0; ‘Nej, bara provat hur det smakar’=1; ‘Nej, jag har rökt e-cigaretter men slutat’=2; ‘Ja, ibland men inte varje dag’=3; ‘Ja, dagligen’=4; ‘’=NA”, as.factor = F)

Som blir “0:2=0;3=1;4=2”

Code
hist(df$FNY12020r, col = RISEprimGreen)

Och även F18 för snus.

Code
hist(df$F18r, col = RISEprimGreen)

10.8.1 Separerade på respektive substans

Code
# for FNY12020r and F14r (e-cig and smoking)

itemlabelsPlotFaktor <- cbind(senaste4v,
                              c("Rökning","Snus","Alkohol","Narkotika (inkl. cannabis)","E-cigaretter")) %>% 
  as.data.frame() %>% 
  rename(itemnr = senaste4v,
         item = V2)
  

andtsUseShare <- function(andts) {
  plotFaktor <- andts
  plotFaktorName <- itemlabelsPlotFaktor %>% 
    filter(itemnr == plotFaktor) %>% 
    pull(item)
  
  df %>%
    filter(Kön %in% c("Pojke", "Flicka"),
           !ARSKURS == "<NA>") %>%
    select(all_of(senaste4v), ar, Kön, ARSKURS) %>%
    mutate(
      bruk4v = case_when(
        .data[[plotFaktor]] == 0 ~ "Ej använt",
        .data[[plotFaktor]] == 1 ~ "Ibland men inte varje dag",
        .data[[plotFaktor]] == 2 ~ "Dagligen",
        TRUE ~ "Svar saknas"
      )
    ) %>% 
    mutate(bruk4v = factor(bruk4v, levels = c("Dagligen","Ibland men inte varje dag","Ej använt","Svar saknas"))) %>% 
    group_by(ar, Kön, ARSKURS) %>%
    count(bruk4v, .drop = FALSE) %>%
    mutate(Andel = (100 * n / sum(n)) %>% round(digits = 1)) %>%
    ggplot(aes(x = ar, y = Andel)) +
    geom_area(aes(fill = bruk4v),
      position = "stack",
      alpha = 0.85
    ) +
    scale_fill_manual(values = c("#D55E00", "#F0E442", "#009E73", "lightgrey")) +
    scale_y_continuous(breaks = c(0, 20, 40, 60, 80, 100)) +
    scale_x_continuous(breaks = årtal, guide = guide_axis(n.dodge = 2)) +
    xlab("Årtal") +
    ylab("Andel i %") +
    theme(
      axis.text.x = element_text(size = ax.size, family = "sans"),
      axis.text.y = element_text(size = ax.size, family = "sans"),
      title = element_text(size = title.size),
      legend.text = element_text(size = legend.size),
      strip.text.x = element_text(size = 14),
      panel.spacing = unit(0.5, "cm", data = NULL)
    ) +
    labs(
      title = paste0(plotFaktorName),
      subtitle = "Uppdelat på kön"
    ) +
    facet_grid(ARSKURS ~ Kön)
}
Code
andtsUseShare("F14r")

Code
andtsUseShare("F18r")

Code
# for f36r and F49r
andtsUseShare2 <- function(andts) {
  plotFaktor <- andts
  plotFaktorName <- itemlabelsPlotFaktor %>% 
    filter(itemnr == plotFaktor) %>% 
    pull(item)
  
  df %>%
    filter(Kön %in% c("Pojke", "Flicka"),
           !ARSKURS == "<NA>") %>%
    select(all_of(senaste4v), ar, Kön, ARSKURS) %>%
    mutate(
      bruk4v = case_when(
        .data[[plotFaktor]] == 0 ~ "Ej använt",
        .data[[plotFaktor]] == 1 ~ "En gång",
        .data[[plotFaktor]] == 2 ~ "Två gånger",
        .data[[plotFaktor]] == 3 ~ "Tre gånger eller fler",
        TRUE ~ "Svar saknas"
      )
    ) %>% 
    mutate(bruk4v = factor(bruk4v, levels = c("Tre gånger eller fler","Två gånger","En gång","Ej använt","Svar saknas"))) %>% 
    group_by(ar, Kön, ARSKURS) %>%
    count(bruk4v, .drop = FALSE) %>%
    mutate(Andel = (100 * n / sum(n)) %>% round(digits = 1)) %>%
    ggplot(aes(x = ar, y = Andel)) +
    geom_area(aes(fill = bruk4v),
      position = "stack",
      alpha = 0.85
    ) +
    scale_fill_manual(values = c("#D55E00", "orange", "#F0E442", "#009E73", "lightgrey")) +
    scale_y_continuous(breaks = c(0, 20, 40, 60, 80, 100)) +
    scale_x_continuous(breaks = årtal, guide = guide_axis(n.dodge = 2)) +
    xlab("Årtal") +
    ylab("Andel i %") +
    theme(
      axis.text.x = element_text(size = ax.size, family = "sans"),
      axis.text.y = element_text(size = ax.size, family = "sans"),
      title = element_text(size = title.size),
      legend.text = element_text(size = legend.size),
      strip.text.x = element_text(size = 14),
      panel.spacing = unit(0.5, "cm", data = NULL)
    ) +
    labs(
      title = paste0(plotFaktorName, ", användning senaste 4 veckorna"),
      subtitle = "Uppdelat på kön"
    ) +
    facet_grid(ARSKURS ~ Kön)
}
Code
andtsUseShare2("F36new")

Code
andtsUseShare2("F49new")

10.8.2 Indexvärde för bruk under senaste 4v

Om vi slår samman “F14r”,“F18r”,“F36new”,“F49new”,“FNY12020r” kan man max ha 2+2+3+3+3 = 12

Code
hist(df$Senaste4v, col = RISEprimGreen)

Code
df %>% count(Senaste4v) %>% formattable()
Senaste4v n
0 63514
1 12001
2 10284
3 8489
4 5579
5 3968
6 1901
7 743
8 382
9 181
10 88
11 3
12 2

Dock finns ingen viktning i ovanstående, så allt bruk likställs, utöver att det går att rapportera högre nivå av alkohol och narkotika, där det är viktigt att notera att den sistnämna inkluderar cannabis.

Code
df %>% 
  select(all_of(senaste4v)) %>% 
  pivot_longer(everything()) %>% 
  ggplot(aes(x = value, fill = name)) +
  geom_histogram()

F14r = rökning F18r = snus f36r = alkohol F49r = narkotika (cannabis eller annan narkotika) GNY12020r = e-cigaretter

Ovanstående är alla år sammanslaget. Nedan fördelat på årtal.

Code
df %>% 
  select(all_of(senaste4v),ar) %>% 
  pivot_longer(senaste4v) %>% 
  ggplot(aes(x = value, fill = name)) +
  geom_histogram() +
  facet_wrap(~ factor(ar))

Code
df %>% 
  select(all_of(senaste4v),ar) %>% 
  pivot_longer(senaste4v) %>% 
  ggplot(aes(x = value, fill = name)) +
  geom_histogram() +
  facet_grid(factor(ar) ~ name)

10.8.2.1 Test visualisering oviktat index “Bruk senaste 4v”

Utifrån siffrorna i tabellen tidigare ter det sig rimligt att slå samman de som har värden på 6 eller mer. Vi ska också testa att gruppera de som har x antal bruk.

Code
plotFaktor = "Senaste4v"
df %>%
  filter(Kön %in% c("Pojke", "Flicka"),
         !ARSKURS == "<NA>") %>%
  select(Senaste4v, ar, Kön, ARSKURS) %>%
  mutate(Senaste4v = recode(Senaste4v,"7:10=6")) %>% 
  mutate(Senaste4v = factor(Senaste4v,
         levels = rev(c(0:6))
         )
         ) %>% 
  #levels = c("Tre gånger eller fler","Två gånger","En gång","Ej använt","Svar saknas"))) %>% 
  group_by(ar, Kön, ARSKURS) %>%
  count(Senaste4v, .drop = FALSE) %>%
  mutate(Andel = (100 * n / sum(n)) %>% round(digits = 1)) %>%
  ggplot(aes(x = ar, y = Andel)) +
  geom_area(aes(fill = Senaste4v),
            position = "stack",
            alpha = 0.85
  ) +
  #scale_fill_manual(values = c("#D55E00", "orange", "#F0E442", "#009E73", "lightgrey")) +
  scale_fill_viridis_d() +
  scale_y_continuous(breaks = c(0, 20, 40, 60, 80, 100)) +
  scale_x_continuous(breaks = årtal, guide = guide_axis(n.dodge = 2)) +
  xlab("Årtal") +
  ylab("Andel i %") +
  theme(
    axis.text.x = element_text(size = ax.size, family = "sans"),
    axis.text.y = element_text(size = ax.size, family = "sans"),
    title = element_text(size = title.size),
    legend.text = element_text(size = legend.size),
    strip.text.x = element_text(size = 14),
    panel.spacing = unit(0.5, "cm", data = NULL)
  ) +
  labs(
    title = paste0("Användning senaste 4 veckorna, oviktat index"),
    subtitle = "Uppdelat på kön"
  ) +
  facet_grid(ARSKURS ~ Kön)

Code
#c("6","5","4","3","2","1","0")

10.8.3 Blandbruk

E-cigaretter ej med pga enbart data från 2020. Snusning finns ej med, kan läggas till om så önskas.

Code
plotFaktor = "Senaste4v"

df %>%
  filter(Kön %in% c("Pojke", "Flicka"),
         !ARSKURS == "<NA>") %>%
  select(all_of(senaste4v), Senaste4v, ar, Kön, ARSKURS) %>%
  mutate(
    bruk4v = case_when(
      Senaste4v == 0 ~ "Ej använt",
      F14r == 1 | F36new == 1 | F49new == 1 ~ "En substans en gång",
      F14r >= 1 & F36new >= 1 ~ "Rökning och alkohol en gång eller oftare",
      F14r >= 1 & F49new >= 1 ~ "Rökning och narkotika en gång eller oftare",
      F36new >= 1 & F49new >= 1 ~ "Alkohol och narkotika en gång eller oftare",
      F14r >= 1 & F36new >= 1 & F49new >= 1 ~ "Alla tre substanser en gång eller oftare",
      TRUE ~ "Svar saknas"
    )
  ) %>% 
  mutate(bruk4v = recode(bruk4v,"NA='Svar saknas'")) %>% 
  mutate(bruk4v = factor(bruk4v, levels = c("Alla tre substanser en gång eller oftare",
                                            "Alkohol och narkotika en gång eller oftare",
                                            "Rökning och narkotika en gång eller oftare",
                                            "Rökning och alkohol en gång eller oftare",
                                            "En substans en gång",
                                            "Ej använt",
                                            "Svar saknas")
  )) %>% 
  select(bruk4v,ar,Kön,ARSKURS) %>% 
  group_by(ar, Kön, ARSKURS) %>%
  count(bruk4v, .drop = FALSE) %>%
  mutate(Andel = (100 * n / sum(n)) %>% round(digits = 1)) %>%
  ggplot(aes(x = ar, y = Andel)) +
  geom_area(aes(fill = bruk4v),
            position = "stack",
            alpha = 0.85
  ) +
  scale_fill_viridis_d(labels = function(x) str_wrap(x, width = 14)) +
  scale_y_continuous(breaks = c(0, 20, 40, 60, 80, 100)) +
  scale_x_continuous(breaks = årtal, guide = guide_axis(n.dodge = 2)) +
  xlab("Årtal") +
  ylab("Andel i %") +
  theme(
    axis.text.x = element_text(size = ax.size, family = "sans"),
    axis.text.y = element_text(size = ax.size, family = "sans"),
    title = element_text(size = title.size),
    legend.text = element_text(size = legend.size),
    strip.text = element_text(size = 12),
    panel.spacing = unit(0.5, "cm", data = NULL)
  ) +
  labs(
    title = paste0("Blandbruk, användning senaste 4 veckorna"),
    subtitle = "Uppdelat på kön"
  ) +
  facet_grid(ARSKURS ~ Kön)

10.8.4 Utan icke-brukare/saknade svar

Code
df %>%
  filter(Kön %in% c("Pojke", "Flicka"),
         !ARSKURS == "<NA>") %>%
  select(all_of(senaste4v), Senaste4v, ar, Kön, ARSKURS) %>%
  mutate(
    bruk4v = case_when(
      Senaste4v == 0 ~ "Ej använt",
      F14r == 1 ~ "Enbart rökning",
      F36new == 1 ~ "Enbart alkohol",
      F49new == 1 ~ "Enbart narkotika",
      F14r >= 1 & F36new >= 1 ~ "Rökning och alkohol en gång eller oftare",
      F14r >= 1 & F49new >= 1 ~ "Rökning och narkotika en gång eller oftare",
      F36new >= 1 & F49new >= 1 ~ "Alkohol och narkotika en gång eller oftare",
      F14r >= 1 & F36new >= 1 & F49new >= 1 ~ "Alla tre substanser en gång eller oftare",
      TRUE ~ "Svar saknas"
    )
  ) %>% 
  mutate(bruk4v = recode(bruk4v,"'Svar saknas'=NA;'Ej använt'=NA")) %>% 
  mutate(bruk4v = factor(bruk4v, levels = c("Alla tre substanser en gång eller oftare",
                                            "Alkohol och narkotika en gång eller oftare",
                                            "Rökning och narkotika en gång eller oftare",
                                            "Rökning och alkohol en gång eller oftare",
                                            "Enbart narkotika",
                                            "Enbart alkohol",
                                            "Enbart rökning")
  )) %>% 
  filter(!is.na(bruk4v)) %>% 
  select(bruk4v,ar,Kön,ARSKURS) %>% 
  group_by(ar, Kön, ARSKURS) %>%
  count(bruk4v, .drop = FALSE) %>%
  mutate(Andel = (100 * n / sum(n)) %>% round(digits = 1)) %>%
  ggplot(aes(x = ar, y = Andel)) +
  geom_area(aes(fill = bruk4v),
            position = "stack",
            alpha = 0.85
  ) +
  #scale_fill_manual(values = c("#D55E00", "orange", "#F0E442", "#009E73", "lightgrey")) +
  scale_fill_viridis_d(labels = function(x) str_wrap(x, width = 14)) +
  scale_y_continuous(breaks = c(0, 20, 40, 60, 80, 100)) +
  scale_x_continuous(breaks = årtal, guide = guide_axis(n.dodge = 2)) +
  xlab("Årtal") +
  ylab("Andel i %") +
  theme(
    axis.text.x = element_text(size = ax.size, family = "sans"),
    axis.text.y = element_text(size = ax.size, family = "sans"),
    title = element_text(size = title.size),
    legend.text = element_text(size = legend.size),
    strip.text = element_text(size = 12),
    panel.spacing = unit(0.5, "cm", data = NULL)
  ) +
  labs(
    title = paste0("Blandbruk, användning senaste 4 veckorna"),
    subtitle = "Uppdelat på kön"
  ) +
  facet_grid(ARSKURS ~ Kön)

10.8.5 Tabell

Code
library(gt)
library(gtExtras)

andtsTable <- function(year) {
df %>%
  filter(Kön %in% c("Pojke", "Flicka"),
         !ARSKURS == "<NA>") %>%
  filter(ar == year) %>% 
  select(all_of(senaste4v), Senaste4v, ar, Kön, ARSKURS) %>%
  # mutate(
  #   bruk4v = case_when(
  #     Senaste4v == 0 ~ "Ej använt",
  #     F14r == 1 | F36new == 1 | F49new == 1 ~ "En substans en gång",
  #     F14r > 1 & F36new > 1 ~ "Rökning och alkohol mer än en gång",
  #     F14r > 1 & F49new > 1 ~ "Rökning och narkotika mer än en gång",
  #     F36new > 1 & F49new > 1 ~ "Alkohol och narkotika mer än en gång",
  #     F14r > 1 & F36new > 1 & F49new > 1 ~ "Alla tre substanser mer än en gång",
  #     TRUE ~ "Svar saknas"
  #   )
  # ) %>% 
  # mutate(bruk4v = recode(bruk4v,"NA='Svar saknas'")) %>% 
  # mutate(bruk4v = factor(bruk4v, levels = c("Alla tre substanser mer än en gång",
  #                                           "Alkohol och narkotika mer än en gång",
  #                                           "Rökning och narkotika mer än en gång",
  #                                           "Rökning och alkohol mer än en gång",
  #                                           "En substans en gång",
  #                                           "Ej använt",
  #                                           "Svar saknas")
  # )) %>% 
  mutate(
    bruk4v = case_when(
      Senaste4v == 0 ~ "Ej använt",
      F14r == 1 ~ "Enbart rökning",
      F36new == 1 ~ "Enbart alkohol",
      F49new == 1 ~ "Enbart narkotika",
      F14r >= 1 & F36new >= 1 ~ "Rökning och alkohol en gång eller oftare",
      F14r >= 1 & F49new >= 1 ~ "Rökning och narkotika en gång eller oftare",
      F36new >= 1 & F49new >= 1 ~ "Alkohol och narkotika en gång eller oftare",
      F14r >= 1 & F36new >= 1 & F49new >= 1 ~ "Alla tre substanser en gång eller oftare",
      TRUE ~ "Svar saknas"
    )
  ) %>% 
  mutate(bruk4v = recode(bruk4v,"'Svar saknas'=NA;'Ej använt'=NA")) %>% 
  mutate(bruk4v = factor(bruk4v, levels = c("Alla tre substanser en gång eller oftare",
                                            "Alkohol och narkotika en gång eller oftare",
                                            "Rökning och narkotika en gång eller oftare",
                                            "Rökning och alkohol en gång eller oftare",
                                            "Enbart narkotika",
                                            "Enbart alkohol",
                                            "Enbart rökning")
  )) %>% 
  select(bruk4v,ar,Kön,ARSKURS) %>% 
  group_by(ar, ARSKURS, Kön) %>%
  count(bruk4v, .drop = FALSE) %>%
  mutate(Andel = (100 * n / sum(n)) %>% round(digits = 1)) %>% 
  renamer = ar,
         Årskurs = ARSKURS,
         Bruk = bruk4v) %>% 
  gt(.,
   groupname_col = c("Årskurs","Kön"),
   rowname_col = "År") %>% 
  gt_theme_espn() %>% 
  tab_options(table.font.name = "Lato",
              container.width = 500,
              heading.align = "left") %>% 
  cols_align(align = "right")
}
Code
andtsTable(2006)
Bruk n Andel
Åk 9 - Flicka
2006 Alla tre substanser en gång eller oftare 0 0.0
2006 Alkohol och narkotika en gång eller oftare 1 0.0
2006 Rökning och narkotika en gång eller oftare 3 0.1
2006 Rökning och alkohol en gång eller oftare 145 4.8
2006 Enbart narkotika 15 0.5
2006 Enbart alkohol 288 9.6
2006 Enbart rökning 421 14.0
2006 NA 2125 70.9
Åk 9 - Pojke
2006 Alla tre substanser en gång eller oftare 0 0.0
2006 Alkohol och narkotika en gång eller oftare 6 0.2
2006 Rökning och narkotika en gång eller oftare 11 0.4
2006 Rökning och alkohol en gång eller oftare 71 2.4
2006 Enbart narkotika 21 0.7
2006 Enbart alkohol 222 7.6
2006 Enbart rökning 234 8.0
2006 NA 2352 80.6
Gy 2 - Flicka
2006 Alla tre substanser en gång eller oftare 0 0.0
2006 Alkohol och narkotika en gång eller oftare 7 0.2
2006 Rökning och narkotika en gång eller oftare 7 0.2
2006 Rökning och alkohol en gång eller oftare 273 8.4
2006 Enbart narkotika 37 1.1
2006 Enbart alkohol 425 13.1
2006 Enbart rökning 570 17.6
2006 NA 1913 59.2
Gy 2 - Pojke
2006 Alla tre substanser en gång eller oftare 0 0.0
2006 Alkohol och narkotika en gång eller oftare 14 0.5
2006 Rökning och narkotika en gång eller oftare 3 0.1
2006 Rökning och alkohol en gång eller oftare 112 3.8
2006 Enbart narkotika 30 1.0
2006 Enbart alkohol 373 12.5
2006 Enbart rökning 526 17.7
2006 NA 1919 64.5
Code
andtsTable(2010)
Bruk n Andel
Åk 9 - Flicka
2010 Alla tre substanser en gång eller oftare 0 0.0
2010 Alkohol och narkotika en gång eller oftare 2 0.1
2010 Rökning och narkotika en gång eller oftare 9 0.3
2010 Rökning och alkohol en gång eller oftare 157 4.8
2010 Enbart narkotika 36 1.1
2010 Enbart alkohol 255 7.7
2010 Enbart rökning 497 15.0
2010 NA 2348 71.1
Åk 9 - Pojke
2010 Alla tre substanser en gång eller oftare 0 0.0
2010 Alkohol och narkotika en gång eller oftare 6 0.2
2010 Rökning och narkotika en gång eller oftare 18 0.5
2010 Rökning och alkohol en gång eller oftare 143 4.1
2010 Enbart narkotika 32 0.9
2010 Enbart alkohol 219 6.3
2010 Enbart rökning 373 10.7
2010 NA 2694 77.3
Gy 2 - Flicka
2010 Alla tre substanser en gång eller oftare 0 0.0
2010 Alkohol och narkotika en gång eller oftare 11 0.2
2010 Rökning och narkotika en gång eller oftare 14 0.3
2010 Rökning och alkohol en gång eller oftare 423 9.1
2010 Enbart narkotika 70 1.5
2010 Enbart alkohol 607 13.0
2010 Enbart rökning 887 19.0
2010 NA 2650 56.8
Gy 2 - Pojke
2010 Alla tre substanser en gång eller oftare 0 0.0
2010 Alkohol och narkotika en gång eller oftare 30 0.8
2010 Rökning och narkotika en gång eller oftare 18 0.5
2010 Rökning och alkohol en gång eller oftare 238 6.0
2010 Enbart narkotika 82 2.1
2010 Enbart alkohol 483 12.2
2010 Enbart rökning 648 16.3
2010 NA 2466 62.2
Code
andtsTable(2014)
Bruk n Andel
Åk 9 - Flicka
2014 Alla tre substanser en gång eller oftare 0 0.0
2014 Alkohol och narkotika en gång eller oftare 1 0.0
2014 Rökning och narkotika en gång eller oftare 2 0.1
2014 Rökning och alkohol en gång eller oftare 48 1.8
2014 Enbart narkotika 29 1.1
2014 Enbart alkohol 182 7.0
2014 Enbart rökning 298 11.4
2014 NA 2050 78.5
Åk 9 - Pojke
2014 Alla tre substanser en gång eller oftare 0 0.0
2014 Alkohol och narkotika en gång eller oftare 3 0.1
2014 Rökning och narkotika en gång eller oftare 3 0.1
2014 Rökning och alkohol en gång eller oftare 47 1.7
2014 Enbart narkotika 20 0.7
2014 Enbart alkohol 133 4.9
2014 Enbart rökning 171 6.4
2014 NA 2313 86.0
Gy 2 - Flicka
2014 Alla tre substanser en gång eller oftare 0 0.0
2014 Alkohol och narkotika en gång eller oftare 1 0.0
2014 Rökning och narkotika en gång eller oftare 9 0.2
2014 Rökning och alkohol en gång eller oftare 198 5.4
2014 Enbart narkotika 40 1.1
2014 Enbart alkohol 444 12.1
2014 Enbart rökning 614 16.8
2014 NA 2355 64.3
Gy 2 - Pojke
2014 Alla tre substanser en gång eller oftare 0 0.0
2014 Alkohol och narkotika en gång eller oftare 18 0.6
2014 Rökning och narkotika en gång eller oftare 12 0.4
2014 Rökning och alkohol en gång eller oftare 100 3.3
2014 Enbart narkotika 53 1.7
2014 Enbart alkohol 348 11.4
2014 Enbart rökning 424 13.9
2014 NA 2086 68.6
Code
andtsTable(2018)
Bruk n Andel
Åk 9 - Flicka
2018 Alla tre substanser en gång eller oftare 0 0.0
2018 Alkohol och narkotika en gång eller oftare 2 0.1
2018 Rökning och narkotika en gång eller oftare 9 0.3
2018 Rökning och alkohol en gång eller oftare 33 1.2
2018 Enbart narkotika 18 0.7
2018 Enbart alkohol 130 4.8
2018 Enbart rökning 263 9.6
2018 NA 2272 83.3
Åk 9 - Pojke
2018 Alla tre substanser en gång eller oftare 0 0.0
2018 Alkohol och narkotika en gång eller oftare 7 0.3
2018 Rökning och narkotika en gång eller oftare 5 0.2
2018 Rökning och alkohol en gång eller oftare 15 0.5
2018 Enbart narkotika 25 0.9
2018 Enbart alkohol 110 3.9
2018 Enbart rökning 116 4.2
2018 NA 2516 90.1
Gy 2 - Flicka
2018 Alla tre substanser en gång eller oftare 0 0.0
2018 Alkohol och narkotika en gång eller oftare 8 0.3
2018 Rökning och narkotika en gång eller oftare 11 0.4
2018 Rökning och alkohol en gång eller oftare 104 3.4
2018 Enbart narkotika 49 1.6
2018 Enbart alkohol 352 11.4
2018 Enbart rökning 526 17.1
2018 NA 2033 65.9
Gy 2 - Pojke
2018 Alla tre substanser en gång eller oftare 0 0.0
2018 Alkohol och narkotika en gång eller oftare 25 0.9
2018 Rökning och narkotika en gång eller oftare 4 0.1
2018 Rökning och alkohol en gång eller oftare 47 1.6
2018 Enbart narkotika 68 2.4
2018 Enbart alkohol 304 10.6
2018 Enbart rökning 328 11.4
2018 NA 2089 72.9
Code
andtsTable(2020)
Bruk n Andel
Åk 9 - Flicka
2020 Alla tre substanser en gång eller oftare 0 0.0
2020 Alkohol och narkotika en gång eller oftare 7 0.2
2020 Rökning och narkotika en gång eller oftare 1 0.0
2020 Rökning och alkohol en gång eller oftare 50 1.5
2020 Enbart narkotika 27 0.8
2020 Enbart alkohol 208 6.4
2020 Enbart rökning 312 9.7
2020 NA 2627 81.3
Åk 9 - Pojke
2020 Alla tre substanser en gång eller oftare 0 0.0
2020 Alkohol och narkotika en gång eller oftare 7 0.2
2020 Rökning och narkotika en gång eller oftare 5 0.2
2020 Rökning och alkohol en gång eller oftare 19 0.6
2020 Enbart narkotika 41 1.2
2020 Enbart alkohol 172 5.2
2020 Enbart rökning 208 6.3
2020 NA 2870 86.4
Gy 2 - Flicka
2020 Alla tre substanser en gång eller oftare 0 0.0
2020 Alkohol och narkotika en gång eller oftare 9 0.3
2020 Rökning och narkotika en gång eller oftare 7 0.2
2020 Rökning och alkohol en gång eller oftare 103 3.3
2020 Enbart narkotika 38 1.2
2020 Enbart alkohol 352 11.1
2020 Enbart rökning 552 17.4
2020 NA 2104 66.5
Gy 2 - Pojke
2020 Alla tre substanser en gång eller oftare 0 0.0
2020 Alkohol och narkotika en gång eller oftare 28 1.0
2020 Rökning och narkotika en gång eller oftare 5 0.2
2020 Rökning och alkohol en gång eller oftare 40 1.4
2020 Enbart narkotika 57 1.9
2020 Enbart alkohol 331 11.3
2020 Enbart rökning 361 12.3
2020 NA 2106 71.9

10.8.6 Missing data över tid

Code
df %>% 
  select(all_of(senaste4v),ar) %>% 
  pivot_longer(senaste4v) %>% 
  filter(is.na(value),
         !name == "FNY12020r") %>% 
  group_by(ar,name) %>% 
  summarise(n = n()) %>% 
  #mutate(Value = recode(value,"NA=1")) %>% 
  ggplot(aes(x = factor(ar), y = n, color = name, group = name)) +
  geom_point(size = 2) +
  geom_line()

10.9 Föräldrafrågor

Code
itemsANDTSfldr <- c("F17","F21","f22","F40","FNY22020")
df.fldr <- df %>% 
  select(all_of(itemsANDTSfldr)) %>% 
  na.omit()

Fråga f22 är summerad utifrån antalet familjemedlemmar som röker eller snusar, och har därför fler möjliga svarsalternativ.

Övriga frågor har tre möjliga svar, utifrån frågan om huruvida eleven “får” använda en substans för föräldrarna:

  • ‘Nej’=0;
  • ‘Vet inte’=1;
  • ‘Ja’=2;
Code
RIlistItemsMargin(df.fldr, 13)
itemnr item
F17 Får du röka för dina föräldrar?
F21 Får du snusa för dina föräldrar?
f22 Använder någon i din familj tobak (röker eller snusar)?
F40 Får du dricka alkohol för dina föräldrar?
FNY22020 Får du satsa pengar på spel för dina föräldrar?

10.9.1 Deskriptiv statistik

Code
RItileplot(df.fldr)

Code
RIlistItemsMargin(df.fldr, fontsize = 11)
itemnr item
F17 Får du röka för dina föräldrar?
F21 Får du snusa för dina föräldrar?
f22 Använder någon i din familj tobak (röker eller snusar)?
F40 Får du dricka alkohol för dina föräldrar?
FNY22020 Får du satsa pengar på spel för dina föräldrar?
Code
RIitemfitPCM2(df.fldr, 400, 16, 8)
OutfitMSQ InfitMSQ OutfitZSTD InfitZSTD
F17 0.517 0.654 -3.442 -3.358
F21 0.6 0.666 -3.781 -3.91
f22 0.988 1.043 -0.325 0.578
F40 0.869 0.896 -1.443 -1.678
FNY22020 1.121 1.065 1.542 0.882
Code
RIpcmPCA(df.fldr)
PCA of Rasch model residuals
Eigenvalues
1.98
1.23
1.15
0.62
0.01
Code
RIloadLoc(na.omit(df.fldr))

Code
RIresidcorr(df.fldr, cutoff = 0.2)
F17 F21 f22 F40 FNY22020
F17
F21 0.49
f22 -0.3 -0.34
F40 0.09 0.14 -0.44
FNY22020 -0.06 -0.02 -0.31 -0.1
Note:
Relative cut-off value (highlighted in red) is 0.115, which is 0.2 above the average correlation.
Code
RItargeting(df.fldr)

Code
RIitemHierarchy(df.fldr)

Som väntat passar inte f22 in bland övriga frågor, vilket syns tydligt på figuren med faktorladdning på första residualkontrasten.

Gällande residualkorrelationer finns ett mycket starkt samband mellan röka och snusa. Det finns även ett samband mellan snusa och alkohol som är något över gränsvärdet.

Vi tar bort f22 och tittar på svarskategorier för övriga frågor

Code
df.fldr$f22 <- NULL

10.9.2 Svarskategorier

Code
plot(mirt.rasch, type="trace")

Att koda “Vet ej” som mitten på svarsskalan var ett test, och det verkar ha fungerat acceptabelt förutom för F40. Vi kodar om “Vet ej” som missing/NA.

Code
df.fldr$F40 <- recode(df.fldr$F40,"1=NA;2=1")
df.erm <- PCM(df.fldr)
plotICC(df.erm, item.subset = "F40")

Code
RItargeting(df.fldr)

Code
RIitemparams(df.fldr,"ANDTSfldr.csv")
Threshold 1 Threshold 2 Item location
F17 0.39 0.96 0.67
F21 -0.26 0.78 0.26
F40 -0.89 NA -0.89
FNY22020 -1.12 1.13 0.01

Det är inte möjligt att ta fram något indexvärde, men det bör vara möjligt att ta fram en variabel som säger något om föräldrarnas tillåtande attityd, vilket är en känd riskfaktor för bruk av ANDTS.

En utgångspunkt kan vara ett gränsvärdet på person location -1.5, utifrån item-parametrarna i tabellen ovan.

Code
df.fldr$FLDRscore <- RIestThetas2(df.fldr, cpu = 8)

hist(df.fldr$FLDRscore, col = RISEprimGreen)

Code
ggplot(df.fldr,(aes(x = FLDRscore))) +
  geom_histogram(fill = RISEprimGreen, bins = 40)

Code
df.fldr %>% 
  mutate(Score = case_when(FLDRscore < -1.5 ~ "Låg risk",
                           TRUE ~ "Förhöjd risk")
         )%>% 
  count(Score)
         Score    n
1 Förhöjd risk 5646
2     Låg risk 4988

Eller så kan vi skilja ut de som svarat “Vet ej” eller “Ja” på någon av frågorna som “Förhöjd risk”.

Code
df.fldr %>%
  mutate(Fldr = rowSums(across(any_of(itemsANDTSfldr)))) %>%
  mutate(Score = case_when(Fldr > 0 ~ "Förhöjd risk",
                           TRUE ~ "Låg risk")
         )%>%
  count(Score)
         Score    n
1 Förhöjd risk 4503
2     Låg risk 6131

Alternativt att skilja ut de som svarat “Ja” på någon av dessa fyra frågor, jämfört med övriga.

Code
df.fldr %>% 
  mutate(Score = case_when(F17 == 2 | F21 == 2 | F40 == 1 | FNY22020 == 2 ~ "Förhöjd risk",
                           TRUE ~ "Låg risk")
         )%>%
  count(Score)
         Score    n
1 Förhöjd risk 3070
2     Låg risk 7564

Båda dessa varianter kan testas i sambandsanalyser med andra variabler för att identifiera vilken som förefaller mest korrekt att använda.

10.10 Programvara som använts

Code
pkgs <- cite_packages(cite.tidyverse = TRUE, 
                      output = "table",
                      bib.file = "grateful-refs.bib",
                      include.RStudio = TRUE)
formattable(pkgs, 
            table.attr = 'class=\"table table-striped\" style="font-size: 14px; font-family: Lato; width: 80%"')
Package Version Citation
arrow 10.0.0 Richardson et al. (2022)
base 4.2.2 R Core Team (2022)
car 3.1.1 Fox and Weisberg (2019)
cowplot 1.1.1 Wilke (2020)
eRm 1.0.2 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); Mair, Hatzinger, and Maier (2021)
foreach 1.5.2 Microsoft and Weston (2022)
formattable 0.2.1 Ren and Russell (2021)
ggrepel 0.9.3 Slowikowski (2023)
glue 1.6.2 Hester and Bryan (2022)
grateful 0.1.11 Rodríguez-Sánchez, Jackson, and Hutchins (2022)
gt 0.8.0 Iannone et al. (2022)
gtExtras 0.4.3 Mock (2022)
kableExtra 1.3.4 Zhu (2021)
knitr 1.42 Xie (2014); Xie (2015); Xie (2023)
matrixStats 0.63.0 Bengtsson (2022)
mirt 1.37.1 Chalmers (2012)
psych 2.2.9 Revelle (2022)
psychotree 0.16.0 Trepte and Verbeet (2010); Strobl, Wickelmaier, and Zeileis (2011); Strobl, Kopf, and Zeileis (2015); Komboz, Zeileis, and Strobl (2018); Wickelmaier and Zeileis (2018)
reshape 0.8.9 Wickham (2007)
RISEkbmRasch 0.1.12 Johansson (2023)
rmarkdown 2.20 Xie, Allaire, and Grolemund (2018); Xie, Dervieux, and Riederer (2020); Allaire et al. (2023)
tidyverse 2.0.0 Wickham et al. (2019)

10.11 Referenser

Allaire, JJ, Yihui Xie, Jonathan McPherson, Javier Luraschi, Kevin Ushey, Aron Atkins, Hadley Wickham, Joe Cheng, Winston Chang, and Richard Iannone. 2023. Rmarkdown: Dynamic Documents for r. https://github.com/rstudio/rmarkdown.
Bengtsson, Henrik. 2022. matrixStats: Functions That Apply to Rows and Columns of Matrices (and to Vectors). https://CRAN.R-project.org/package=matrixStats.
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. https://doi.org/10.1177/0146621619835501.
Fox, John, and Sanford Weisberg. 2019. An R Companion to Applied Regression. Third. Thousand Oaks CA: Sage. https://socialsciences.mcmaster.ca/jfox/Books/Companion/.
Hatzinger, Reinhold, and Thomas Rusch. 2009. IRT models with relaxed assumptions in eRm: A manual-like instruction.” Psychology Science Quarterly 51.
Hester, Jim, and Jennifer Bryan. 2022. Glue: Interpreted String Literals. https://CRAN.R-project.org/package=glue.
Iannone, Richard, Joe Cheng, Barret Schloerke, Ellis Hughes, and JooYoung Seo. 2022. Gt: Easily Create Presentation-Ready Display Tables. https://CRAN.R-project.org/package=gt.
Johansson, Magnus. 2023. RISEkbmRasch: Psychometric Analysis in r with Rasch Measurement Theory. https://github.com/pgmj/RISEkbmRasch.
Koller, Ingrid, Marco Johannes 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.
Mair, Patrick, and Reinhold Hatzinger. 2007a. CML based estimation of extended Rasch models with the eRm package in R.” Psychology Science 49.
———. 2007b. Extended Rasch modeling: The eRm package for the application of IRT models in R.” Journal of Statistical Software 20. https://www.jstatsoft.org/v20/i09.
Mair, Patrick, Reinhold Hatzinger, and Marco Johannes Maier. 2021. eRm: Extended Rasch Modeling. https://cran.r-project.org/package=eRm.
Microsoft, and Steve Weston. 2022. Foreach: Provides Foreach Looping Construct. https://CRAN.R-project.org/package=foreach.
Mock, Thomas. 2022. gtExtras: Extending ’Gt’ for Beautiful HTML Tables. https://CRAN.R-project.org/package=gtExtras.
R Core Team. 2022. R: A Language and Environment for Statistical Computing. Vienna, Austria: R Foundation for Statistical Computing. https://www.R-project.org/.
Ren, Kun, and Kenton Russell. 2021. Formattable: Create ’Formattable’ Data Structures. https://CRAN.R-project.org/package=formattable.
Revelle, William. 2022. Psych: Procedures for Psychological, Psychometric, and Personality Research. Evanston, Illinois: Northwestern University. https://CRAN.R-project.org/package=psych.
Richardson, Neal, Ian Cook, Nic Crane, Dewey Dunnington, Romain François, Jonathan Keane, Dragoș Moldovan-Grünfeld, Jeroen Ooms, and Apache Arrow. 2022. Arrow: Integration to ’Apache’ ’Arrow’. https://CRAN.R-project.org/package=arrow.
Rodríguez-Sánchez, Francisco, Connor P. Jackson, and Shaurita D. Hutchins. 2022. Grateful: Facilitate Citation of r Packages. https://github.com/Pakillo/grateful.
Rusch, Thomas, Marco Johannes 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.
Slowikowski, Kamil. 2023. Ggrepel: Automatically Position Non-Overlapping Text Labels with ’Ggplot2’. https://CRAN.R-project.org/package=ggrepel.
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.
Trepte, Sabine, and Markus Verbeet, eds. 2010. Allgemeinbildung in Deutschland – Erkenntnisse Aus Dem SPIEGEL Studentenpisa-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.
Wilke, Claus O. 2020. Cowplot: Streamlined Plot Theme and Plot Annotations for ’Ggplot2’. https://CRAN.R-project.org/package=cowplot.
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.
Xie, Yihui, Christophe Dervieux, and Emily Riederer. 2020. R Markdown Cookbook. Boca Raton, Florida: Chapman; Hall/CRC. https://bookdown.org/yihui/rmarkdown-cookbook.
Zhu, Hao. 2021. kableExtra: Construct Complex Table with ’Kable’ and Pipe Syntax. https://CRAN.R-project.org/package=kableExtra.