Displayr can analyze MaxDiff variables from a variety of survey platforms, but depending on how they have been set up, you may need to reformat them first. One such example is the output from Qualtrics' dedicated MaxDiff module.
For example, let us suppose you have respondents choose which company they like the most (best) and which the least (worst) from several alternative lists of companies.
- Displayr's version of MaxDiff analysis requires separate Best and Worst variables for each question or task, and that the alternative labels (company names) are the category options.
- Typically this is programmed in Qualtrics (and similar platforms) as a series of matrix questions with piped alternatives, whereby the variables are by company name for each question or task, and the category labels represent the Best or Worst selections.
Requirements
A data set with MaxDiff variable sets where the alternatives are the variables and the Best and Worst selections are the category labels, as per the above example.
- These instructions cater to a non-randomized single version design and a randomized multiple version design.
- Make sure your MaxDiff selection variables and any variables that store the attributes shown (when your design is randomized) have each been set up as a set of Nominal - Multi questions, one for each task or iteration in the design. If your design asks each respondent to evaluate 4 sets of alternatives 6 times, then there should be 6 sets of Nominal - Multi variables made up of 4 variables each in your project.
Method
Part 1 – Tidy the data
This just makes things easier later on. Let's say you have 6 MaxDiff variable sets, Q14 to Q19, which represent each question or iteration of the MaxDiff survey question.
- In the Data Sets tree, select Q14
- In the Object Inspector, select Properties > GENERAL > Label and change the label to MD1
- Repeat steps 1 and 2 for each of Q15 to Q19.
The result should end up looking like this: - If you have a randomized design, you will also have a set of variables that store the attributes shown to each respondent. These should similarly be labeled MD1A to MD6A to help with later steps.
Part 2 – Add the Design
If you have an external design, you can paste this into your document using Table > Paste or Enter Table. Otherwise you can use R code to create a design based on your data. In this example, we will do the latter.
- Select Anything > Calculation > Custom Code and click anywhere on the page.
-
Click on your page where you wish to have this Calculation inserted, and drag to create a box for the output.
-
Enter a name under GENERAL > Name. In this example, we will change the name to design.
-
Enter your R code in the object inspector under Properties > R CODE. For non-randomized single version designs, you should use the below code:
questions = list(MD1, MD2, MD3, MD4, MD5, MD6)
n.questions = length(questions)
question.attributes = lapply(questions, colnames)
alts.per.question = length(question.attributes[[1]])
attributes = unique(unlist(question.attributes))
design = matrix(NA, nrow = n.questions, ncol = alts.per.question + 2)
colnames(design) = c('Version', 'Question', paste0('Option.', 1:alts.per.question))
design[, 'Version'] = rep(1,nrow(design))
design[, 'Question'] = 1:n.questions
for (q in 1:n.questions) {
for (a in 1:alts.per.question) {
design[q, a + 2] = which(attributes == question.attributes[[q]][a])
}
}
design
Note, the first line should be updated to reflect all your MaxDiff selection variable sets by name.
For randomized multiple version designs, you would use the below instead:
pipe.questions = list(MD1A, MD2A, MD3A, MD4A, MD5A, MD6A)
n.questions = length(pipe.questions)
version = vers_MAXDIFF
des = unique(data.frame(version,pipe.questions))
des = des[!is.na(des$version),]
des = des[order(des$version),]
des = data.frame(lapply(des, as.numeric))
variables.to.stack = list(
'Option.1' = c(2,6,10,14,18,22),
'Option.2' = c(3,7,11,15,19,23),
'Option.3' = c(4,8,12,16,20,24),
'Option.4' = c(5,9,13,17,21,25))
design = reshape(data = des,
idvar = 'version', direction = 'long',
varying = variables.to.stack)
names(design) = c('Version', 'Question', names(variables.to.stack))
design = design[order(design$Version,design$Question),]
Note, the first line should be updated to reflect all your MaxDiff variable sets by name that store the attributes shown.
- Ensure the name of your version variable is correctly referenced in line 3.
- On lines 10 to 13 there should be one row per option shown in your MaxDiff survey per screen. The indices referenced within the
c()
identify the column to pull data from. Option 1 should start from column 2 and increment by the number of options (i.e. 4), while Option 2 starts from column 3 and increments by the same number, and so on.
Part 3 – Create the best/worst variables
- Click the plus sign
when you hover over any variable in the Data Sets tree
- From the Insert Variable(s) menu, select Custom Code > Multiple R Variables > Numeric to create a Numeric - Multi variable set.
- Type the number of variables you want to create in the How Many Variables Do You Want to Create? box. In this example, we will create 12 new variables (6 best variables and 6 worst variables)
- Click OK
Each of the variables in this variable set shares the same R template code, that is used to create empty variables. - The next step is to update the template code with the following R code
- In the Data Set tree, click on Variable 1 in the New R Variable Set. The current code will be in the object inspector > Properties >R CODE box.
- For a non-randomized single version design, insert the following code on line 17, just before line of code that says new.data
Note, you will need to make the following edits to the code:
- Update the second line to list out the names of all of your MaxDiff variable sets.
- Update the fourth and fifth lines with the labels of the best and worst categories in your MaxDiff variable sets.
#Update with the names of the MaxDiff variable sets
questions = list(MD1, MD2, MD3, MD4, MD5, MD6)
#Update with the labels of the best and worst categories in the MaxDiff variable sets
bestlabel = "Most important"
worstlabel = "Least important"
removeHTML <- function(htmlString) {
return(gsub('<.*>', '', htmlString))
}
n.questions = length(questions)
question.attributes = lapply(questions, colnames)
alts.per.question = length(question.attributes[[1]])
attributes = removeHTML(unique(unlist(question.attributes)))
md.list = list()
get.best.worst = function (question, attributes, best.label = bestlabel, worst.label = worstlabel) {
option.selected.in.row = function (v) {
option = v[v != 'FALSE']
if (length(option) == 0) {
return(NA)
} else {
return(option)
}
}
q = question
q.labels = matrix(colnames(q), nrow = nrow(q), ncol = ncol(q), byrow = TRUE)
q.best = q == best.label & !is.na(q)
q.best[q.best] = q.labels[q.best]
q.best = apply(q.best, 1, option.selected.in.row)
q.worst = q == worst.label & !is.na(q)
q.worst[q.worst] = q.labels[q.worst]
q.worst = apply(q.worst, 1, option.selected.in.row)
q.best = factor(q.best, levels = attributes)
q.worst = factor(q.worst, levels = attributes)
best.worst = data.frame(q.best, q.worst)
}
for (i in 1:n.questions) {
md = get.best.worst(questions[[i]], attributes = attributes)
md.list[[i]] = md
}
x = do.call(cbind, md.list)
colnames(x) = paste0(colnames(x), rep(1:n.questions, each = 2))
new.data = x - For a randomized multiple version design, you will need to use and edit the below code instead:
- Update the second line to list out the names of all of your MaxDiff variable sets, and the fourth line to list out the names of all the variable sets that store the attributes that were shown.
- Update the sixth and seventh lines with the labels of the best and worst categories in your MaxDiff variable sets.
#Update with the names of the MaxDiff variable sets
questions = list(MD1, MD2, MD3, MD4, MD5, MD6)
#Update with the names of the variable sets that store what attributes were shown
pipe.questions = list(MD1A, MD2A, MD3A, MD4A, MD5A, MD6A)
#Update with the labels of the best and worst categories in the MaxDiff variable sets
bestlabel = "Most important"
worstlabel = "Least important"
removeHTML <- function(htmlString) {
return(gsub('<.*>', '', htmlString))
}
n.questions = length(questions)
question.attributes = lapply(questions, colnames)
alts.per.question = length(question.attributes[[1]])
attributes = removeHTML(levels(pipe.questions[[1]][[1]]))
md.list = list()
get.best.worst = function (question, pipe.questions, attributes, best.label = bestlabel, worst.label = worstlabel) {
option.selected.in.row = function (v) {
option = v[v != 'FALSE']
if (length(option) == 0) {
return(NA)
} else {
return(option)
}
}
q = question
q.labels = pipe.questions[[i]]
q.best = q == best.label & !is.na(q)
q.best[q.best] = q.labels[q.best]
q.best = apply(q.best, 1, option.selected.in.row)
q.worst = q == worst.label & !is.na(q)
q.worst[q.worst] = q.labels[q.worst]
q.worst = apply(q.worst, 1, option.selected.in.row)
q.best = factor(q.best, levels = attributes)
q.worst = factor(q.worst, levels = attributes)
best.worst = data.frame(q.best, q.worst)
}
for (i in 1:n.questions) {
md = get.best.worst(questions[[i]], pipe.questions, attributes = attributes)
md.list[[i]] = md
}
x = do.call(cbind, md.list)
colnames(x) = paste0(colnames(x), rep(1:n.questions, each = 2))
new.data = x
9. The Data Sets tree should now look like this:
10. Click on New R Variable Set in the Data Sets tree
11. In the Object Inspector, change the structure to Nominal - Multi Grid with unordered categories
The results are as follows:
12. Drag the new variable set onto the page
The questions are now ready to be analyzed in Displayr.
Next
How to Create a MaxDiff Experimental Design
How to Do MaxDiff Latent Class Analysis
How to Use Hierarchical Bayes for MaxDiff
How to Import Data from Qualtrics