This is the Quarto file containing the R chunks with the analyses for the Universiteit van Nederland movie available at https://youtu.be/dlCGnS4AyOg.
The OSF repo for this project is https://osf.io/4ysbz, and the git repo is https://gitlab.com/matherion/nano-mcda-uvnl/. The rendered version of this file is hosted at https://matherion.gitlab.io/nano-mcda-uvnl/.
Code
### "Slugs": parts of variable names used for easy selection
criteriaSlugs <- c("damageSelf", "damageOther",
"benefits", "addiction");
names(criteriaSlugs) <- criteriaSlugs;
drugSlugs <- c("alcohol", "cannabis", "cocaine",
"ecstasy", "coffee");
names(drugSlugs) <- drugSlugs;
criteriaSlugs_recoded <- paste0(criteriaSlugs, "Recoded");
names(criteriaSlugs_recoded) <- criteriaSlugs_recoded;
drugSlugs_recoded <- paste0(drugSlugs, "Recoded");
names(drugSlugs_recoded) <- drugSlugs_recoded;
titles <-
list(criterion =
list(damageSelf = "Schade gebruiker",
damageOther = "Schade anderen",
benefits = "Voordelen",
addiction = "Verslavingsrisico"),
drug =
list(
alcohol = "Alcohol🍻",
cannabis = "Cannabis🚬",
cocaine = "Cocaine👃",
ecstasy = "Ecstasy💊",
coffee = "Koffie☕"
)
);
weightSigns <-
list(
damageSelf = 1,
damageOther = 1,
benefits = -1,
addiction = 1
);
Function definitions
Code
ratingsToScores <- function(ratings,
weights,
weightOrder = names(weightSigns)) {
return(mean(ratings * (unlist(weightSigns[weightOrder]) * weights)));
}
Loading data
Here, we import the LimeSurvey data. Note that these data can be downloaded from the git repository at https://gitlab.com/matherion/nano-mcda-uvnl/.
Code
### Import data
dat.raw <-
limonaid::ls_import_data(
sid = 669115,
path = here::here("data")
);
Clean data
Here, we clean the data.
Code
### Delete unfinished entries
dat <-
dat.raw[!is.na(dat.raw$submitdate), ];
### Rescale weights in case the highest weight was not 10
for (i in 1:nrow(dat)) {
dat[i, paste0("weights_", names(titles$criterion))] <-
as.numeric(trimws(dat[i, paste0("weights_", names(titles$criterion))]));
multiplier <-
10 / max(dat[i, paste0("weights_", names(titles$criterion))]);
dat[i, paste0("correctedWeights_", names(titles$criterion))] <-
multiplier * dat[i, paste0("weights_", names(titles$criterion))];
}
### Subtract 1 from every rating, so they run from 0-4
dat[, apply(expand.grid(criteriaSlugs_recoded, drugSlugs), 1, paste, collapse="_")] <-
dat[, apply(expand.grid(criteriaSlugs, drugSlugs), 1, paste, collapse="_")] - 1;
### Multiply "benefits" ratings with -1 (they're not negative; "reverse damage")
dat[, gsub("benefits", "benefitsRecoded", grep("^benefits", names(dat), value=TRUE))] <-
-1 * dat[, grepl("^benefits", names(dat))];
Rating means
Here, we compute the means of the ratings.
Code
ratingMeans <-
unlist(
lapply(
criteriaSlugs_recoded,
function(criterion) {
return(
lapply(
drugSlugs,
function(drug) {
return(
mean(
dat[, paste(criterion,
drug,
sep = "_")],
na.rm = TRUE
)
);
}
)
);
}
),
recursive = FALSE
);
ratingMeansDf <-
data.frame(
rating = unlist(ratingMeans)
);
ratingMeansDf$criterion =
factor(unlist(lapply(strsplit(names(ratingMeans), "\\."), `[[`, 1)),
levels = unique(unlist(lapply(strsplit(names(ratingMeans), "\\."), `[[`, 1))),
ordered = TRUE);
ratingMeansDf$drug =
factor(unlist(lapply(strsplit(names(ratingMeans), "\\."), `[[`, 2)),
levels = unique(unlist(lapply(strsplit(names(ratingMeans), "\\."), `[[`, 2))),
ordered = TRUE);
### Also invert benefits ratings here
ratingMeansDf[ratingMeansDf$criterion == "benefits", "rating"] <-
ratingMeansDf[ratingMeansDf$criterion == "benefits", "rating"] * -1;
Aggregate scores
Here, we compute the aggregated scores.
Code
### Weights
meanWeights <-
colMeans(
dat[, grep("correctedWeights_", names(dat), value=TRUE)]
);
meanWeights_rescaled <- (10 / max(meanWeights)) * meanWeights;
names(meanWeights) <-
names(titles$criterion);
### Add to rating means
ratingMeansDf$weight <-
meanWeights_rescaled[ratingMeansDf$criterion];
ratingMeansDf$weightedRating <-
ratingMeansDf$rating * ratingMeansDf$weight;
meanScores <- list();
for (drug in names(titles$drug)) {
meanScores[[drug]] <-
ratingsToScores(
ratingMeansDf[ratingMeansDf$drug == drug, 'rating'],
meanWeights_rescaled * 2,
weightOrder = 1
);
}
meanScoresDf <-
data.frame(
drug = names(titles$drug),
score = unlist(meanScores)
);
These sections show the frequencies of each rating for each drug and histograms visualizing the same information.
Rating frequencies
Code
ratingFreqs <-
unlist(
lapply(
criteriaSlugs_recoded,
function(criterion) {
return(
lapply(
drugSlugs,
function(drug) {
return(
table(
dat[, paste(criterion,
drug,
sep = "_")]
)
);
}
)
);
}
),
recursive = FALSE
);
print(ratingFreqs);
$damageSelfRecoded.alcohol
1 2 3 4
1 5 12 30
$damageSelfRecoded.cannabis
0 1 2 3 4
6 14 20 6 2
$damageSelfRecoded.cocaine
1 2 3 4
1 10 22 15
$damageSelfRecoded.ecstasy
0 1 2 3 4
5 22 14 3 4
$damageSelfRecoded.coffee
0 1 2 3
42 4 1 1
$damageOtherRecoded.alcohol
0 1 2 3 4
1 1 2 5 39
$damageOtherRecoded.cannabis
0 1 2 3 4
7 18 19 3 1
$damageOtherRecoded.cocaine
1 2 3 4
2 7 24 15
$damageOtherRecoded.ecstasy
0 1 2 3 4
9 24 9 2 4
$damageOtherRecoded.coffee
0 1 2
42 4 2
$benefitsRecoded.alcohol
-5 -4 -3 -2 -1
1 3 17 16 11
$benefitsRecoded.cannabis
-5 -4 -3 -2 -1
6 8 16 13 5
$benefitsRecoded.cocaine
-5 -4 -3 -2 -1
1 1 8 12 26
$benefitsRecoded.ecstasy
-5 -4 -3 -2 -1
18 6 14 4 6
$benefitsRecoded.coffee
-5 -4 -3 -2 -1
20 11 9 4 4
$addictionRecoded.alcohol
2 3 4
8 22 18
$addictionRecoded.cannabis
0 1 2 3 4
4 7 23 11 3
$addictionRecoded.cocaine
1 2 3 4
2 3 15 28
$addictionRecoded.ecstasy
0 1 2 3
32 11 3 2
$addictionRecoded.coffee
0 1 2 3 4
10 13 10 6 9
Rating histograms
Code
ratingPlots <-
unlist(
lapply(
criteriaSlugs,
function(criterion) {
return(
lapply(
drugSlugs,
function(drug) {
res <-
ggplot2::ggplot(
dat,
mapping = ggplot2::aes(
x = .data[[paste(criterion,
drug,
sep = "_")]]
)
) +
ggplot2::geom_bar(na.rm = TRUE) +
ggplot2::coord_cartesian(
xlim = c(1, 5),
ylim = c(1, max(unlist(ratingFreqs)))
) +
ggplot2::scale_x_continuous(
breaks = 1:5
) +
ggplot2::labs(
x = NULL,
y = NULL,
title =
paste0(
titles$drug[[drug]],
", ",
titles$criterion[[criterion]]
)
) +
ggplot2::theme_minimal();
if (criterion != criteriaSlugs[1]) {
res <- res +
ggplot2::theme(
axis.title.y = ggplot2::element_blank(),
axis.text.y = ggplot2::element_blank(),
axis.ticks.y = ggplot2::element_blank()
);
}
if (drug != drugSlugs[5]) {
res <- res +
ggplot2::theme(
axis.title.x = ggplot2::element_blank(),
axis.text.x = ggplot2::element_blank(),
axis.ticks.x = ggplot2::element_blank()
);
}
return(res);
}
)
);
}
),
recursive = FALSE
);
patchwork::wrap_plots(
ratingPlots,
byrow = FALSE,
ncol = 4,
guides = "collect"
);
