8 Conjoint analysis

In this chapter, you will learn how to carry out a conjoint analysis. Conjoint analysis starts from a survey in which people rate or choose between products (e.g., cars) that differ on a number of attributes (e.g., safety, fuel efficiency, comfort, etc). From these ratings or choices, the analysis determines the value that people place on the different product attributes (e.g., how much weight do people place on safety when choosing between cars). This information can then be used in product development.

8.1 Data

8.1.1 Import

We will analyze data from a survey in which 15 consumers were asked to rate ten ice creams. Each ice cream had a different ‘profile’, i.e., a different combination of levels of four attributes: flavor (raspberry, chocolate, strawberry, mango, vanilla), packaging (homemade waffle, cone, pint), light (low fat or not), and organic (organic or not). All 15 respondents rated the ten profiles by providing a score between 1 and 10.

We use data provided by www.xlstat.com that are described in their tutorial on doing conjoint analysis in Excel. Download the data here.

library(tidyverse)
library(readxl)

icecream <- read_excel("icecream.xlsx") # No need to include the sheet argument when there's only one sheet in the Excel file

8.1.2 Manipulate

icecream
## # A tibble: 10 × 20
##    Observations Flavor Packa…¹ Light Organic Indiv…² Indiv…³ Indiv…⁴ Indiv…⁵ Indiv…⁶ Indiv…⁷ Indiv…⁸ Indiv…⁹
##    <chr>        <chr>  <chr>   <chr> <chr>     <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
##  1 Profile 1    Raspb… Homema… No l… Not or…       1       6       5       1       2       7       7       5
##  2 Profile 2    Choco… Cone    No l… Organic       4       7       4       2       6       4       4       6
##  3 Profile 3    Raspb… Pint    Low … Organic       2       1       6       5       1       8       8       2
##  4 Profile 4    Straw… Pint    No l… Organic       7       5       3       4       7       1      10       8
##  5 Profile 5    Straw… Cone    Low … Not or…       9       8       2       3       5       2       9       3
##  6 Profile 6    Choco… Homema… No l… Not or…       3       2       8      10       4       3       3       1
##  7 Profile 7    Vanil… Pint    Low … Not or…       5       9       7       9       3       5       5       9
##  8 Profile 8    Mango  Homema… Low … Organic      10      10       9       7      10       9       2       7
##  9 Profile 9    Mango  Pint    No l… Not or…       6       4      10       6       9       6       6      10
## 10 Profile 10   Vanil… Homema… No l… Organic       8       3       1       8       8      10       1       4
## # … with 7 more variables: `Individual 9` <dbl>, `Individual 10` <dbl>, `Individual 11` <dbl>,
## #   `Individual 12` <dbl>, `Individual 13` <dbl>, `Individual 14` <dbl>, `Individual 15` <dbl>, and
## #   abbreviated variable names ¹​Packaging, ²​`Individual 1`, ³​`Individual 2`, ⁴​`Individual 3`,
## #   ⁵​`Individual 4`, ⁶​`Individual 5`, ⁷​`Individual 6`, ⁸​`Individual 7`, ⁹​`Individual 8`

When we inspect the data, we see that we have a column for every respondent. This is an unusual way of storing data (normally we have one row per respondent), so let’s restructure our dataset with the pivot_longer function (as we’ve done before):

icecream <- icecream %>% 
  pivot_longer(cols = starts_with("Individual"), names_to = "respondent", values_to = "rating") %>% # respondent keeps track of the respondent, rating will store the respondent's ratings, and we want to stack every variable that starts with Individual
  rename("profile" = "Observations") %>% # rename Observations to profile
  mutate(profile = factor(profile), respondent = factor(respondent),  # factorize identifiers
         Flavor = factor(Flavor), Packaging = factor(Packaging), Light = factor(Light), Organic = factor(Organic)) # factorize the ice cream attributes


# Wide dataset: one row per unit of observation (here: profile) and a number of columns for the different observations (here: respondents)
# Long dataset: one row per observation (here: profile x respondent combination)

# Converting from wide to long means that we're stacking a number of columns on top of each other.
# The pivot_longer function converts datasets from wide to long and takes three arguments:
# 1. The cols argument: here we tell R which columns we want to stack. The original dataset had 10 rows with 15 columns for 15 individuals. The long dataset will have 150 rows with 150 values for 15 individuals. This means we need to keep track of which individual we're dealing with.
# 2. The names_to argument: here you define the name of the variable that keeps track of which individual we're dealing with.
# 3. The values_to argument: here you define the name of the variable that stores the actual values.

icecream
## # A tibble: 150 × 7
##    profile   Flavor    Packaging       Light      Organic     respondent    rating
##    <fct>     <fct>     <fct>           <fct>      <fct>       <fct>          <dbl>
##  1 Profile 1 Raspberry Homemade waffle No low fat Not organic Individual 1       1
##  2 Profile 1 Raspberry Homemade waffle No low fat Not organic Individual 2       6
##  3 Profile 1 Raspberry Homemade waffle No low fat Not organic Individual 3       5
##  4 Profile 1 Raspberry Homemade waffle No low fat Not organic Individual 4       1
##  5 Profile 1 Raspberry Homemade waffle No low fat Not organic Individual 5       2
##  6 Profile 1 Raspberry Homemade waffle No low fat Not organic Individual 6       7
##  7 Profile 1 Raspberry Homemade waffle No low fat Not organic Individual 7       7
##  8 Profile 1 Raspberry Homemade waffle No low fat Not organic Individual 8       5
##  9 Profile 1 Raspberry Homemade waffle No low fat Not organic Individual 9       1
## 10 Profile 1 Raspberry Homemade waffle No low fat Not organic Individual 10     10
## # … with 140 more rows

It’s better to use the Viewer here (double-click on the icecream object in the Environment pane or do View(icecream)) to see that there are ten rows (10 profiles) per respondent now.

The remaining variables are:

  • profile is an identifier for the different ice creams

  • Flavor, Packaging, Light, Organic are the four attributes that make up the profile of an ice cream

8.1.3 Recap: importing & manipulating

Here’s what we’ve done so far, in one orderly sequence of piped operations (download the data here:

library(tidyverse)
library(readxl)

icecream <- read_excel("icecream.xlsx") %>% 
  gather(respondent, rating, starts_with("Individual")) %>% # respondent keeps track of the respondent, rating will store the respondent's ratings, and we want to stack every variable that starts with Individual
  rename("profile" = "Observations") %>% 
  mutate(profile = factor(profile), respondent = factor(respondent),
         Flavor = factor(Flavor), Packaging = factor(Packaging), Light = factor(Light), Organic = factor(Organic))

8.2 Design of experiments

When we inspect our dataset, we see that Flavor has 5 levels (raspberry, chocolate, strawberry, mango, vanilla), Packaging has 3 levels (homemade waffle, cone, pint), Light has 2 levels (low fat vs. not), and Organic has 2 levels (organic vs. not). The goal of a conjoint analysis is to estimate the extent to which each attribute level affects the rating of the ice cream. To do this, the ice cream manufacturer could create 5 \(\times\) 3 \(\times\) 2 \(\times\) 2 = 60 different ice creams and ask people to rate all of these. This will give the manufacturer a good estimate of the importance of each attribute and all their possible interactions. However, rating 60 ice creams is difficult for the participants and such a large study would be expensive for the manufacturer to fund. In practice, researchers in this situation will ask people to rate a subset of those 60 ice creams. In this section, we discuss how to select a subset (e.g., 10 ice creams) of all possible attribute level combinations (i.e., 60 ice creams) that will still allow us to get good estimates of the most important effects.

In the dataset, we already have the ratings for ten profiles, so the decision of which ice creams to test has already been made. However, let’s disregard the fact that we already have the data and consider the decisions that need to be made before collecting data. In other words, let’s discuss how we go from a full factorial (all 60 combinations) to a fractional design (less than 60 combinations).

The doe (design of experiments) function from the radiant package will help us decide on study designs. Radiant is an R package for business analytics. The following discussion of the doe function is based on Radiant’s discussion of this function.

install.packages("radiant")
library(radiant)

To use doe we need to input the information about our attributes and their levels in a specific way:

# attribute1, attribute2, etc. are vectors with one element in which we first provide the name of the attribute followed by a semi-colon and then provide all the levels of the attributes separated by semi-colons
attribute1 <- "Flavor; Raspberry; Chocolate; Strawberry; Mango; Vanilla"
attribute2 <- "Package; Homemade waffle; Cone; Pint"
attribute3 <- "Light; Low fat; No low fat"
attribute4 <- "Organic; Organic; Not organic"

# now combine these different attributes into one vector with c()
attributes <- c(attribute1, attribute2, attribute3, attribute4)

We can now ask for potential experimental designs:

summary(doe(attributes, seed = 123)) # Seed: fix random number generator, see explanation below
## Experimental design
## # trials for partial factorial: 60 
## # trials for full factorial   : 60 
## Random seed                   : 123 
## 
## Attributes and levels:
## Flavor: Raspberry, Chocolate, Strawberry, Mango, Vanilla 
## Package: Homemade_waffle, Cone, Pint 
## Light: Low_fat, No_low_fat 
## Organic: Organic, Not_organic 
## 
## Design efficiency:
##  Trials D-efficiency Balanced
##       9        0.105    FALSE
##      10        0.389    FALSE
##      11        0.411    FALSE
##      12        0.614    FALSE
##      13        0.542    FALSE
##      14        0.479    FALSE
##      15        0.762    FALSE
##      16        0.738    FALSE
##      17        0.748    FALSE
##      18        0.756    FALSE
##      19        0.644    FALSE
##      20        0.895    FALSE
##      21        0.848    FALSE
##      22        0.833    FALSE
##      23        0.790    FALSE
##      24        0.827    FALSE
##      25        0.787    FALSE
##      26        0.768    FALSE
##      27        0.759    FALSE
##      28        0.736    FALSE
##      29        0.702    FALSE
##      30        0.984     TRUE
##      31        0.952    FALSE
##      32        0.933    FALSE
##      33        0.928    FALSE
##      34        0.900    FALSE
##      35        0.871    FALSE
##      36        0.893    FALSE
##      37        0.866    FALSE
##      38        0.843    FALSE
##      39        0.836    FALSE
##      40        0.922    FALSE
##      41        0.899    FALSE
##      42        0.904    FALSE
##      43        0.882    FALSE
##      44        0.861    FALSE
##      45        0.949    FALSE
##      46        0.919    FALSE
##      47        0.912    FALSE
##      48        0.911    FALSE
##      49        0.891    FALSE
##      50        0.959    FALSE
##      51        0.939    FALSE
##      52        0.944    FALSE
##      53        0.925    FALSE
##      54        0.924    FALSE
##      55        0.906    FALSE
##      56        0.902    FALSE
##      57        0.884    FALSE
##      58        0.872    FALSE
##      59        0.855    FALSE
##      60        1.000     TRUE
## 
## Partial factorial design correlations:
## ** Note: Variables are assumed to be ordinal **
##         Flavor Package Light Organic
## Flavor       1       0     0       0
## Package      0       1     0       0
## Light        0       0     1       0
## Organic      0       0     0       1
## 
## Partial factorial design:
##  trial     Flavor         Package      Light     Organic
##      1  Raspberry Homemade_waffle    Low_fat     Organic
##      2  Raspberry Homemade_waffle    Low_fat Not_organic
##      3  Raspberry Homemade_waffle No_low_fat     Organic
##      4  Raspberry Homemade_waffle No_low_fat Not_organic
##      5  Raspberry            Cone    Low_fat     Organic
##      6  Raspberry            Cone    Low_fat Not_organic
##      7  Raspberry            Cone No_low_fat     Organic
##      8  Raspberry            Cone No_low_fat Not_organic
##      9  Raspberry            Pint    Low_fat     Organic
##     10  Raspberry            Pint    Low_fat Not_organic
##     11  Raspberry            Pint No_low_fat     Organic
##     12  Raspberry            Pint No_low_fat Not_organic
##     13  Chocolate Homemade_waffle    Low_fat     Organic
##     14  Chocolate Homemade_waffle    Low_fat Not_organic
##     15  Chocolate Homemade_waffle No_low_fat     Organic
##     16  Chocolate Homemade_waffle No_low_fat Not_organic
##     17  Chocolate            Cone    Low_fat     Organic
##     18  Chocolate            Cone    Low_fat Not_organic
##     19  Chocolate            Cone No_low_fat     Organic
##     20  Chocolate            Cone No_low_fat Not_organic
##     21  Chocolate            Pint    Low_fat     Organic
##     22  Chocolate            Pint    Low_fat Not_organic
##     23  Chocolate            Pint No_low_fat     Organic
##     24  Chocolate            Pint No_low_fat Not_organic
##     25 Strawberry Homemade_waffle    Low_fat     Organic
##     26 Strawberry Homemade_waffle    Low_fat Not_organic
##     27 Strawberry Homemade_waffle No_low_fat     Organic
##     28 Strawberry Homemade_waffle No_low_fat Not_organic
##     29 Strawberry            Cone    Low_fat     Organic
##     30 Strawberry            Cone    Low_fat Not_organic
##     31 Strawberry            Cone No_low_fat     Organic
##     32 Strawberry            Cone No_low_fat Not_organic
##     33 Strawberry            Pint    Low_fat     Organic
##     34 Strawberry            Pint    Low_fat Not_organic
##     35 Strawberry            Pint No_low_fat     Organic
##     36 Strawberry            Pint No_low_fat Not_organic
##     37      Mango Homemade_waffle    Low_fat     Organic
##     38      Mango Homemade_waffle    Low_fat Not_organic
##     39      Mango Homemade_waffle No_low_fat     Organic
##     40      Mango Homemade_waffle No_low_fat Not_organic
##     41      Mango            Cone    Low_fat     Organic
##     42      Mango            Cone    Low_fat Not_organic
##     43      Mango            Cone No_low_fat     Organic
##     44      Mango            Cone No_low_fat Not_organic
##     45      Mango            Pint    Low_fat     Organic
##     46      Mango            Pint    Low_fat Not_organic
##     47      Mango            Pint No_low_fat     Organic
##     48      Mango            Pint No_low_fat Not_organic
##     49    Vanilla Homemade_waffle    Low_fat     Organic
##     50    Vanilla Homemade_waffle    Low_fat Not_organic
##     51    Vanilla Homemade_waffle No_low_fat     Organic
##     52    Vanilla Homemade_waffle No_low_fat Not_organic
##     53    Vanilla            Cone    Low_fat     Organic
##     54    Vanilla            Cone    Low_fat Not_organic
##     55    Vanilla            Cone No_low_fat     Organic
##     56    Vanilla            Cone No_low_fat Not_organic
##     57    Vanilla            Pint    Low_fat     Organic
##     58    Vanilla            Pint    Low_fat Not_organic
##     59    Vanilla            Pint No_low_fat     Organic
##     60    Vanilla            Pint No_low_fat Not_organic
## 
## Estimable effects from partial factorial design:
## 
##   Flavor|Chocolate
##   Flavor|Strawberry
##   Flavor|Mango
##   Flavor|Vanilla
##   Package|Cone
##   Package|Pint
##   Light|No_low_fat
##   Organic|Not_organic
##   Flavor|Chocolate:Package|Cone
##   Flavor|Strawberry:Package|Cone
##   Flavor|Mango:Package|Cone
##   Flavor|Vanilla:Package|Cone
##   Flavor|Chocolate:Package|Pint
##   Flavor|Strawberry:Package|Pint
##   Flavor|Mango:Package|Pint
##   Flavor|Vanilla:Package|Pint
##   Flavor|Chocolate:Light|No_low_fat
##   Flavor|Strawberry:Light|No_low_fat
##   Flavor|Mango:Light|No_low_fat
##   Flavor|Vanilla:Light|No_low_fat
##   Package|Cone:Light|No_low_fat
##   Package|Pint:Light|No_low_fat
##   Flavor|Chocolate:Organic|Not_organic
##   Flavor|Strawberry:Organic|Not_organic
##   Flavor|Mango:Organic|Not_organic
##   Flavor|Vanilla:Organic|Not_organic
##   Package|Cone:Organic|Not_organic
##   Package|Pint:Organic|Not_organic
##   Light|No_low_fat:Organic|Not_organic
##   Flavor|Chocolate:Package|Cone:Light|No_low_fat
##   Flavor|Strawberry:Package|Cone:Light|No_low_fat
##   Flavor|Mango:Package|Cone:Light|No_low_fat
##   Flavor|Vanilla:Package|Cone:Light|No_low_fat
##   Flavor|Chocolate:Package|Pint:Light|No_low_fat
##   Flavor|Strawberry:Package|Pint:Light|No_low_fat
##   Flavor|Mango:Package|Pint:Light|No_low_fat
##   Flavor|Vanilla:Package|Pint:Light|No_low_fat
##   Flavor|Chocolate:Package|Cone:Organic|Not_organic
##   Flavor|Strawberry:Package|Cone:Organic|Not_organic
##   Flavor|Mango:Package|Cone:Organic|Not_organic
##   Flavor|Vanilla:Package|Cone:Organic|Not_organic
##   Flavor|Chocolate:Package|Pint:Organic|Not_organic
##   Flavor|Strawberry:Package|Pint:Organic|Not_organic
##   Flavor|Mango:Package|Pint:Organic|Not_organic
##   Flavor|Vanilla:Package|Pint:Organic|Not_organic
##   Flavor|Chocolate:Light|No_low_fat:Organic|Not_organic
##   Flavor|Strawberry:Light|No_low_fat:Organic|Not_organic
##   Flavor|Mango:Light|No_low_fat:Organic|Not_organic
##   Flavor|Vanilla:Light|No_low_fat:Organic|Not_organic
##   Package|Cone:Light|No_low_fat:Organic|Not_organic
##   Package|Pint:Light|No_low_fat:Organic|Not_organic
##   Flavor|Chocolate:Package|Cone:Light|No_low_fat:Organic|Not_organic
##   Flavor|Strawberry:Package|Cone:Light|No_low_fat:Organic|Not_organic
##   Flavor|Mango:Package|Cone:Light|No_low_fat:Organic|Not_organic
##   Flavor|Vanilla:Package|Cone:Light|No_low_fat:Organic|Not_organic
##   Flavor|Chocolate:Package|Pint:Light|No_low_fat:Organic|Not_organic
##   Flavor|Strawberry:Package|Pint:Light|No_low_fat:Organic|Not_organic
##   Flavor|Mango:Package|Pint:Light|No_low_fat:Organic|Not_organic
##   Flavor|Vanilla:Package|Pint:Light|No_low_fat:Organic|Not_organic 
## 
## Full factorial design:
##  trial     Flavor         Package      Light     Organic
##      1  Raspberry Homemade_waffle    Low_fat     Organic
##      2  Raspberry Homemade_waffle    Low_fat Not_organic
##      3  Raspberry Homemade_waffle No_low_fat     Organic
##      4  Raspberry Homemade_waffle No_low_fat Not_organic
##      5  Raspberry            Cone    Low_fat     Organic
##      6  Raspberry            Cone    Low_fat Not_organic
##      7  Raspberry            Cone No_low_fat     Organic
##      8  Raspberry            Cone No_low_fat Not_organic
##      9  Raspberry            Pint    Low_fat     Organic
##     10  Raspberry            Pint    Low_fat Not_organic
##     11  Raspberry            Pint No_low_fat     Organic
##     12  Raspberry            Pint No_low_fat Not_organic
##     13  Chocolate Homemade_waffle    Low_fat     Organic
##     14  Chocolate Homemade_waffle    Low_fat Not_organic
##     15  Chocolate Homemade_waffle No_low_fat     Organic
##     16  Chocolate Homemade_waffle No_low_fat Not_organic
##     17  Chocolate            Cone    Low_fat     Organic
##     18  Chocolate            Cone    Low_fat Not_organic
##     19  Chocolate            Cone No_low_fat     Organic
##     20  Chocolate            Cone No_low_fat Not_organic
##     21  Chocolate            Pint    Low_fat     Organic
##     22  Chocolate            Pint    Low_fat Not_organic
##     23  Chocolate            Pint No_low_fat     Organic
##     24  Chocolate            Pint No_low_fat Not_organic
##     25 Strawberry Homemade_waffle    Low_fat     Organic
##     26 Strawberry Homemade_waffle    Low_fat Not_organic
##     27 Strawberry Homemade_waffle No_low_fat     Organic
##     28 Strawberry Homemade_waffle No_low_fat Not_organic
##     29 Strawberry            Cone    Low_fat     Organic
##     30 Strawberry            Cone    Low_fat Not_organic
##     31 Strawberry            Cone No_low_fat     Organic
##     32 Strawberry            Cone No_low_fat Not_organic
##     33 Strawberry            Pint    Low_fat     Organic
##     34 Strawberry            Pint    Low_fat Not_organic
##     35 Strawberry            Pint No_low_fat     Organic
##     36 Strawberry            Pint No_low_fat Not_organic
##     37      Mango Homemade_waffle    Low_fat     Organic
##     38      Mango Homemade_waffle    Low_fat Not_organic
##     39      Mango Homemade_waffle No_low_fat     Organic
##     40      Mango Homemade_waffle No_low_fat Not_organic
##     41      Mango            Cone    Low_fat     Organic
##     42      Mango            Cone    Low_fat Not_organic
##     43      Mango            Cone No_low_fat     Organic
##     44      Mango            Cone No_low_fat Not_organic
##     45      Mango            Pint    Low_fat     Organic
##     46      Mango            Pint    Low_fat Not_organic
##     47      Mango            Pint No_low_fat     Organic
##     48      Mango            Pint No_low_fat Not_organic
##     49    Vanilla Homemade_waffle    Low_fat     Organic
##     50    Vanilla Homemade_waffle    Low_fat Not_organic
##     51    Vanilla Homemade_waffle No_low_fat     Organic
##     52    Vanilla Homemade_waffle No_low_fat Not_organic
##     53    Vanilla            Cone    Low_fat     Organic
##     54    Vanilla            Cone    Low_fat Not_organic
##     55    Vanilla            Cone No_low_fat     Organic
##     56    Vanilla            Cone No_low_fat Not_organic
##     57    Vanilla            Pint    Low_fat     Organic
##     58    Vanilla            Pint    Low_fat Not_organic
##     59    Vanilla            Pint No_low_fat     Organic
##     60    Vanilla            Pint No_low_fat Not_organic

Look at the output under the header Design efficiency. It shows 52 rows. The rows represent experimental designs with different numbers of Trials or different numbers of ice creams (i.e., attribute level combinations) that would be tested. A better word for trial is profile. For each experimental design, it shows the D-efficiency of the design — a measure of how cleanly we will be able to estimate the effects of interest after running the experiment (higher scores are better) — and whether or not the design is balanced — whether each level is included in the same number of trials or profiles. Ideally, we’re looking for balanced designs with a high D-efficiency (above 0.80 is considered reasonable). We get two candidates, an experimental design with 60 profiles, which is just the full factorial design, or a design with 30 profiles. Let’s have a look at the design with 30 profiles:

summary(doe(attributes, seed = 123, trials = 30))
## Experimental design
## # trials for partial factorial: 30 
## # trials for full factorial   : 60 
## Random seed                   : 123 
## 
## Attributes and levels:
## Flavor: Raspberry, Chocolate, Strawberry, Mango, Vanilla 
## Package: Homemade_waffle, Cone, Pint 
## Light: Low_fat, No_low_fat 
## Organic: Organic, Not_organic 
## 
## Design efficiency:
##  Trials D-efficiency Balanced
##      30        0.984     TRUE
## 
## Partial factorial design correlations:
## ** Note: Variables are assumed to be ordinal **
##         Flavor Package  Light Organic
## Flavor       1       0  0.000   0.000
## Package      0       1  0.000   0.000
## Light        0       0  1.000  -0.105
## Organic      0       0 -0.105   1.000
## 
## Partial factorial design:
##  trial     Flavor         Package      Light     Organic
##      1  Raspberry Homemade_waffle    Low_fat     Organic
##      4  Raspberry Homemade_waffle No_low_fat Not_organic
##      6  Raspberry            Cone    Low_fat Not_organic
##      7  Raspberry            Cone No_low_fat     Organic
##     10  Raspberry            Pint    Low_fat Not_organic
##     11  Raspberry            Pint No_low_fat     Organic
##     13  Chocolate Homemade_waffle    Low_fat     Organic
##     14  Chocolate Homemade_waffle    Low_fat Not_organic
##     19  Chocolate            Cone No_low_fat     Organic
##     20  Chocolate            Cone No_low_fat Not_organic
##     22  Chocolate            Pint    Low_fat Not_organic
##     23  Chocolate            Pint No_low_fat     Organic
##     26 Strawberry Homemade_waffle    Low_fat Not_organic
##     28 Strawberry Homemade_waffle No_low_fat Not_organic
##     29 Strawberry            Cone    Low_fat     Organic
##     32 Strawberry            Cone No_low_fat Not_organic
##     33 Strawberry            Pint    Low_fat     Organic
##     35 Strawberry            Pint No_low_fat     Organic
##     39      Mango Homemade_waffle No_low_fat     Organic
##     40      Mango Homemade_waffle No_low_fat Not_organic
##     41      Mango            Cone    Low_fat     Organic
##     42      Mango            Cone    Low_fat Not_organic
##     46      Mango            Pint    Low_fat Not_organic
##     47      Mango            Pint No_low_fat     Organic
##     49    Vanilla Homemade_waffle    Low_fat     Organic
##     51    Vanilla Homemade_waffle No_low_fat     Organic
##     53    Vanilla            Cone    Low_fat     Organic
##     56    Vanilla            Cone No_low_fat Not_organic
##     58    Vanilla            Pint    Low_fat Not_organic
##     60    Vanilla            Pint No_low_fat Not_organic
## 
## Estimable effects from partial factorial design:
## 
##   Flavor|Chocolate
##   Flavor|Strawberry
##   Flavor|Mango
##   Flavor|Vanilla
##   Package|Cone
##   Package|Pint
##   Light|No_low_fat
##   Organic|Not_organic
##   Flavor|Chocolate:Package|Cone
##   Flavor|Strawberry:Package|Cone
##   Flavor|Mango:Package|Cone
##   Flavor|Vanilla:Package|Cone
##   Flavor|Chocolate:Package|Pint
##   Flavor|Strawberry:Package|Pint
##   Flavor|Mango:Package|Pint
##   Flavor|Vanilla:Package|Pint
##   Flavor|Chocolate:Light|No_low_fat
##   Flavor|Strawberry:Light|No_low_fat
##   Flavor|Mango:Light|No_low_fat
##   Flavor|Vanilla:Light|No_low_fat
##   Package|Cone:Light|No_low_fat
##   Package|Pint:Light|No_low_fat
##   Flavor|Chocolate:Organic|Not_organic
##   Flavor|Strawberry:Organic|Not_organic
##   Flavor|Mango:Organic|Not_organic
##   Flavor|Vanilla:Organic|Not_organic
##   Package|Cone:Organic|Not_organic
##   Light|No_low_fat:Organic|Not_organic
##   Flavor|Strawberry:Package|Pint:Light|No_low_fat 
## 
## Full factorial design:
##  trial     Flavor         Package      Light     Organic
##      1  Raspberry Homemade_waffle    Low_fat     Organic
##      2  Raspberry Homemade_waffle    Low_fat Not_organic
##      3  Raspberry Homemade_waffle No_low_fat     Organic
##      4  Raspberry Homemade_waffle No_low_fat Not_organic
##      5  Raspberry            Cone    Low_fat     Organic
##      6  Raspberry            Cone    Low_fat Not_organic
##      7  Raspberry            Cone No_low_fat     Organic
##      8  Raspberry            Cone No_low_fat Not_organic
##      9  Raspberry            Pint    Low_fat     Organic
##     10  Raspberry            Pint    Low_fat Not_organic
##     11  Raspberry            Pint No_low_fat     Organic
##     12  Raspberry            Pint No_low_fat Not_organic
##     13  Chocolate Homemade_waffle    Low_fat     Organic
##     14  Chocolate Homemade_waffle    Low_fat Not_organic
##     15  Chocolate Homemade_waffle No_low_fat     Organic
##     16  Chocolate Homemade_waffle No_low_fat Not_organic
##     17  Chocolate            Cone    Low_fat     Organic
##     18  Chocolate            Cone    Low_fat Not_organic
##     19  Chocolate            Cone No_low_fat     Organic
##     20  Chocolate            Cone No_low_fat Not_organic
##     21  Chocolate            Pint    Low_fat     Organic
##     22  Chocolate            Pint    Low_fat Not_organic
##     23  Chocolate            Pint No_low_fat     Organic
##     24  Chocolate            Pint No_low_fat Not_organic
##     25 Strawberry Homemade_waffle    Low_fat     Organic
##     26 Strawberry Homemade_waffle    Low_fat Not_organic
##     27 Strawberry Homemade_waffle No_low_fat     Organic
##     28 Strawberry Homemade_waffle No_low_fat Not_organic
##     29 Strawberry            Cone    Low_fat     Organic
##     30 Strawberry            Cone    Low_fat Not_organic
##     31 Strawberry            Cone No_low_fat     Organic
##     32 Strawberry            Cone No_low_fat Not_organic
##     33 Strawberry            Pint    Low_fat     Organic
##     34 Strawberry            Pint    Low_fat Not_organic
##     35 Strawberry            Pint No_low_fat     Organic
##     36 Strawberry            Pint No_low_fat Not_organic
##     37      Mango Homemade_waffle    Low_fat     Organic
##     38      Mango Homemade_waffle    Low_fat Not_organic
##     39      Mango Homemade_waffle No_low_fat     Organic
##     40      Mango Homemade_waffle No_low_fat Not_organic
##     41      Mango            Cone    Low_fat     Organic
##     42      Mango            Cone    Low_fat Not_organic
##     43      Mango            Cone No_low_fat     Organic
##     44      Mango            Cone No_low_fat Not_organic
##     45      Mango            Pint    Low_fat     Organic
##     46      Mango            Pint    Low_fat Not_organic
##     47      Mango            Pint No_low_fat     Organic
##     48      Mango            Pint No_low_fat Not_organic
##     49    Vanilla Homemade_waffle    Low_fat     Organic
##     50    Vanilla Homemade_waffle    Low_fat Not_organic
##     51    Vanilla Homemade_waffle No_low_fat     Organic
##     52    Vanilla Homemade_waffle No_low_fat Not_organic
##     53    Vanilla            Cone    Low_fat     Organic
##     54    Vanilla            Cone    Low_fat Not_organic
##     55    Vanilla            Cone No_low_fat     Organic
##     56    Vanilla            Cone No_low_fat Not_organic
##     57    Vanilla            Pint    Low_fat     Organic
##     58    Vanilla            Pint    Low_fat Not_organic
##     59    Vanilla            Pint No_low_fat     Organic
##     60    Vanilla            Pint No_low_fat Not_organic

Under Partial factorial design (or fractional factorial design), we find the profiles that we could run in an experiment with 30 instead of 60 profiles. Under Partial factorial design correlations, we see that two attributes are correlated, namely Light and Organic (r = -0.105). This will always be the case in fractional factorial designs. It means that some combinations of attribute levels will be more prevalent than others. Only in a full factorial design will all attributes be uncorrelated or orthogonal.

A possible design with only 10 profiles would be unbalanced and would look like this:

summary(doe(attributes, seed = 123, trials = 10))
## Experimental design
## # trials for partial factorial: 10 
## # trials for full factorial   : 60 
## Random seed                   : 123 
## 
## Attributes and levels:
## Flavor: Raspberry, Chocolate, Strawberry, Mango, Vanilla 
## Package: Homemade_waffle, Cone, Pint 
## Light: Low_fat, No_low_fat 
## Organic: Organic, Not_organic 
## 
## Design efficiency:
##  Trials D-efficiency Balanced
##      10        0.389    FALSE
## 
## Partial factorial design correlations:
## ** Note: Variables are assumed to be ordinal **
##         Flavor Package Light Organic
## Flavor   1.000   0.121 0.000   0.000
## Package  0.121   1.000 0.000   0.000
## Light    0.000   0.000 1.000   0.309
## Organic  0.000   0.000 0.309   1.000
## 
## Partial factorial design:
##  trial     Flavor         Package      Light     Organic
##      4  Raspberry Homemade_waffle No_low_fat Not_organic
##      5  Raspberry            Cone    Low_fat     Organic
##     20  Chocolate            Cone No_low_fat Not_organic
##     21  Chocolate            Pint    Low_fat     Organic
##     25 Strawberry Homemade_waffle    Low_fat     Organic
##     36 Strawberry            Pint No_low_fat Not_organic
##     39      Mango Homemade_waffle No_low_fat     Organic
##     46      Mango            Pint    Low_fat Not_organic
##     50    Vanilla Homemade_waffle    Low_fat Not_organic
##     59    Vanilla            Pint No_low_fat     Organic
## 
## Estimable effects from partial factorial design:
## 
##   Flavor|Chocolate
##   Flavor|Strawberry
##   Flavor|Mango
##   Flavor|Vanilla
##   Package|Cone
##   Package|Pint
##   Light|No_low_fat
##   Organic|Not_organic
##   Flavor|Chocolate:Package|Cone 
## 
## Full factorial design:
##  trial     Flavor         Package      Light     Organic
##      1  Raspberry Homemade_waffle    Low_fat     Organic
##      2  Raspberry Homemade_waffle    Low_fat Not_organic
##      3  Raspberry Homemade_waffle No_low_fat     Organic
##      4  Raspberry Homemade_waffle No_low_fat Not_organic
##      5  Raspberry            Cone    Low_fat     Organic
##      6  Raspberry            Cone    Low_fat Not_organic
##      7  Raspberry            Cone No_low_fat     Organic
##      8  Raspberry            Cone No_low_fat Not_organic
##      9  Raspberry            Pint    Low_fat     Organic
##     10  Raspberry            Pint    Low_fat Not_organic
##     11  Raspberry            Pint No_low_fat     Organic
##     12  Raspberry            Pint No_low_fat Not_organic
##     13  Chocolate Homemade_waffle    Low_fat     Organic
##     14  Chocolate Homemade_waffle    Low_fat Not_organic
##     15  Chocolate Homemade_waffle No_low_fat     Organic
##     16  Chocolate Homemade_waffle No_low_fat Not_organic
##     17  Chocolate            Cone    Low_fat     Organic
##     18  Chocolate            Cone    Low_fat Not_organic
##     19  Chocolate            Cone No_low_fat     Organic
##     20  Chocolate            Cone No_low_fat Not_organic
##     21  Chocolate            Pint    Low_fat     Organic
##     22  Chocolate            Pint    Low_fat Not_organic
##     23  Chocolate            Pint No_low_fat     Organic
##     24  Chocolate            Pint No_low_fat Not_organic
##     25 Strawberry Homemade_waffle    Low_fat     Organic
##     26 Strawberry Homemade_waffle    Low_fat Not_organic
##     27 Strawberry Homemade_waffle No_low_fat     Organic
##     28 Strawberry Homemade_waffle No_low_fat Not_organic
##     29 Strawberry            Cone    Low_fat     Organic
##     30 Strawberry            Cone    Low_fat Not_organic
##     31 Strawberry            Cone No_low_fat     Organic
##     32 Strawberry            Cone No_low_fat Not_organic
##     33 Strawberry            Pint    Low_fat     Organic
##     34 Strawberry            Pint    Low_fat Not_organic
##     35 Strawberry            Pint No_low_fat     Organic
##     36 Strawberry            Pint No_low_fat Not_organic
##     37      Mango Homemade_waffle    Low_fat     Organic
##     38      Mango Homemade_waffle    Low_fat Not_organic
##     39      Mango Homemade_waffle No_low_fat     Organic
##     40      Mango Homemade_waffle No_low_fat Not_organic
##     41      Mango            Cone    Low_fat     Organic
##     42      Mango            Cone    Low_fat Not_organic
##     43      Mango            Cone No_low_fat     Organic
##     44      Mango            Cone No_low_fat Not_organic
##     45      Mango            Pint    Low_fat     Organic
##     46      Mango            Pint    Low_fat Not_organic
##     47      Mango            Pint No_low_fat     Organic
##     48      Mango            Pint No_low_fat Not_organic
##     49    Vanilla Homemade_waffle    Low_fat     Organic
##     50    Vanilla Homemade_waffle    Low_fat Not_organic
##     51    Vanilla Homemade_waffle No_low_fat     Organic
##     52    Vanilla Homemade_waffle No_low_fat Not_organic
##     53    Vanilla            Cone    Low_fat     Organic
##     54    Vanilla            Cone    Low_fat Not_organic
##     55    Vanilla            Cone No_low_fat     Organic
##     56    Vanilla            Cone No_low_fat Not_organic
##     57    Vanilla            Pint    Low_fat     Organic
##     58    Vanilla            Pint    Low_fat Not_organic
##     59    Vanilla            Pint No_low_fat     Organic
##     60    Vanilla            Pint No_low_fat Not_organic

Compared to the design with 30 profiles, there are now more and stronger correlations between the attributes.

Note that the profiles are not exactly the same as those in the experiment that was used to collect the ice cream data. This is because, for unbalanced designs, there is some randomness involved in setting the actual attribute level combinations. That is also why we set seed = 123. seed is used to fix R’s random number generator. Setting it to a fixed number (123 or 456 or something else) will make sure that R generates the same output every time. Without setting the seed, doe with trials = 10 would not give the same fractional design every time you run it.

Also note that the radiant package installs an add-in that you can access via Addins (find this button on the right of the row below ‘File’ etc.) -> Start radiant (browser). This will open an app in your browser that will allow you to carry out the steps above in an intuitive visual interface. For help on this, check out Radiant’s discussion of their Design of Experiments module here.

8.3 One respondent

8.3.1 Estimate part-worths and importance weights

While some software requires you to first create dummy variables representing the attribute levels and then run a regression, Radiant does not require you to do so. You can simply use the attributes (each with multiple levels) as variables. We’ll first carry out a conjoint analysis on the data of one respondent (Individual 1):

respondent1 <- icecream %>% filter(respondent == "Individual 1")

# save the conjoint analysis in an object, because we'll use it as input to summary(), plot(), and predict() later on
conjoint_respondent1 <- conjoint(respondent1, rvar = "rating", evar = c("Flavor","Packaging","Light","Organic")) 

summary(conjoint_respondent1)
## Conjoint analysis
## Data                 : respondent1 
## Response variable    : rating 
## Explanatory variables: Flavor, Packaging, Light, Organic 
## 
## Conjoint part-worths:
##    Attributes          Levels     PW
##  Flavor       Chocolate        0.000
##  Flavor       Mango            5.000
##  Flavor       Raspberry       -1.500
##  Flavor       Strawberry       5.000
##  Flavor       Vanilla          3.500
##  Packaging    Cone             0.000
##  Packaging    Homemade waffle  0.000
##  Packaging    Pint            -2.000
##  Light        Low fat          0.000
##  Light        No low fat      -1.000
##  Organic      Not organic      0.000
##  Organic      Organic          1.400
##  Base utility ~                3.800
## 
## Conjoint importance weights:
##  Attributes    IW
##   Flavor    0.596
##   Packaging 0.183
##   Light     0.092
##   Organic   0.128
## 
## Conjoint regression results:
## 
##                            coefficient
##  (Intercept)                     3.800
##  Flavor|Mango                    5.000
##  Flavor|Raspberry               -1.500
##  Flavor|Strawberry               5.000
##  Flavor|Vanilla                  3.500
##  Packaging|Homemade waffle       0.000
##  Packaging|Pint                 -2.000
##  Light|No low fat               -1.000
##  Organic|Organic                 1.400

The output gives part-worths, importance weights, and regression coefficients. The part-worths and the regression coefficients give the same information: compared to the reference level (the first level of an attribute; you’ll see that the part-worths are always zero for this level), how much does each attribute level increase or decrease the rating of an ice cream? We can plot these results:

plot(conjoint_respondent1)

And then we easily see that this person would enjoy a low fat, organic, mango or strawberry ice cream in a cone or one a homemade waffle the most.

Note that the Conjoint regression results are simply the results of a multiple linear regression:

# Run this regression if you're interested in learning which predictor is significant or what the R-squared of the overall model is.
summary(lm(rating ~ Flavor + Packaging + Light + Organic, data = respondent1))
## 
## Call:
## lm(formula = rating ~ Flavor + Packaging + Light + Organic, data = respondent1)
## 
## Residuals:
##    1    2    3    4    5    6    7    8    9   10 
## -0.3 -0.2  0.3 -0.2  0.2  0.2 -0.3 -0.2  0.2  0.3 
## 
## Coefficients:
##                            Estimate Std. Error t value Pr(>|t|)
## (Intercept)               3.800e+00  8.426e-01   4.510    0.139
## FlavorMango               5.000e+00  9.747e-01   5.130    0.123
## FlavorRaspberry          -1.500e+00  9.747e-01  -1.539    0.367
## FlavorStrawberry          5.000e+00  8.660e-01   5.774    0.109
## FlavorVanilla             3.500e+00  9.747e-01   3.591    0.173
## PackagingHomemade waffle  1.570e-15  8.944e-01   0.000    1.000
## PackagingPint            -2.000e+00  8.660e-01  -2.309    0.260
## LightNo low fat          -1.000e+00  5.916e-01  -1.690    0.340
## OrganicOrganic            1.400e+00  4.899e-01   2.858    0.214
## 
## Residual standard error: 0.7746 on 1 degrees of freedom
## Multiple R-squared:  0.9927, Adjusted R-squared:  0.9345 
## F-statistic: 17.06 on 8 and 1 DF,  p-value: 0.1852

Finally, the importance weights tell us how strongly each attribute determines the rating of an ice cream. For this respondent, flavor is the most important attribute and light is the least important attribute. This respondent’s rating is determined for 59.6 percent by flavor and for 9.2 percent by light.

8.3.2 Profiles: predicted utilities

Predicting the ratings (utilities) of the different ice creams is very easy in R. First, let’s make sure we have a dataset with the different profiles that were tested:

profiles <- icecream %>% 
  filter(respondent == "Individual 1") %>% 
  select(Flavor,Packaging,Light,Organic)

profiles
## # A tibble: 10 × 4
##    Flavor     Packaging       Light      Organic    
##    <fct>      <fct>           <fct>      <fct>      
##  1 Raspberry  Homemade waffle No low fat Not organic
##  2 Chocolate  Cone            No low fat Organic    
##  3 Raspberry  Pint            Low fat    Organic    
##  4 Strawberry Pint            No low fat Organic    
##  5 Strawberry Cone            Low fat    Not organic
##  6 Chocolate  Homemade waffle No low fat Not organic
##  7 Vanilla    Pint            Low fat    Not organic
##  8 Mango      Homemade waffle Low fat    Organic    
##  9 Mango      Pint            No low fat Not organic
## 10 Vanilla    Homemade waffle No low fat Organic

Then, we ask the predict function to predict the ratings of the profiles based on the regression function:

predict(conjoint_respondent1, profiles) # predict the ratings for the profiles based on the conjoint analysis
## Conjoint Analysis
## Data                 : respondent1 
## Response variable    : rating 
## Explanatory variables: Flavor, Packaging, Light, Organic 
## Prediction dataset   : profiles 
## 
##      Flavor       Packaging      Light     Organic Prediction
##   Raspberry Homemade waffle No low fat Not organic      1.300
##   Chocolate            Cone No low fat     Organic      4.200
##   Raspberry            Pint    Low fat     Organic      1.700
##  Strawberry            Pint No low fat     Organic      7.200
##  Strawberry            Cone    Low fat Not organic      8.800
##   Chocolate Homemade waffle No low fat Not organic      2.800
##     Vanilla            Pint    Low fat Not organic      5.300
##       Mango Homemade waffle    Low fat     Organic     10.200
##       Mango            Pint No low fat Not organic      5.800
##     Vanilla Homemade waffle No low fat     Organic      7.700

The predicted rating is highest for low fat, organic, mango ice cream on a homemade waffle. But these are predictions for ice creams that the respondent has actually rated. If we wanted to know which ice cream the respondent liked most, we could have just looked at his/her observed (instead of predicted) ratings. It’s more interesting to get predictions for ice creams that the respondent has not rated. For this, we need the profiles for all possible ice creams. We can create these profiles with the expand.grid function. The expand.grid function takes two or more vectors and creates every possible combination of elements of those vectors:

Flavor <- c("Raspberry","Chocolate","Mango","Strawberry","Vanilla")
Organic <- c("Organic","Not organic")

expand.grid(Flavor, Organic)
##          Var1        Var2
## 1   Raspberry     Organic
## 2   Chocolate     Organic
## 3       Mango     Organic
## 4  Strawberry     Organic
## 5     Vanilla     Organic
## 6   Raspberry Not organic
## 7   Chocolate Not organic
## 8       Mango Not organic
## 9  Strawberry Not organic
## 10    Vanilla Not organic

Let’s do this for all our attribute levels:

# there's an easier way to get attribute levels than creating the vectors manually:
levels(icecream$Flavor) # make sure that Flavor is factorized first!
## [1] "Chocolate"  "Mango"      "Raspberry"  "Strawberry" "Vanilla"
# now create all the profiles
profiles.all <- expand.grid(levels(icecream$Flavor),levels(icecream$Packaging),levels(icecream$Light),levels(icecream$Organic)) %>% 
  rename("Flavor" = "Var1", "Packaging" = "Var2", "Light" = "Var3", "Organic" = "Var4") # rename the variables created by expand.grid (don't forget this, otherwise predict won't know where to look for each attribute)

# predict the ratings of all profiles
predict(conjoint_respondent1, profiles.all) %>% 
  arrange(desc(Prediction)) # show the ice creams with the highest predicted rating on top
## Conjoint Analysis
## Data                 : respondent1 
## Response variable    : rating 
## Explanatory variables: Flavor, Packaging, Light, Organic 
## Prediction dataset   : profiles.all 
## Rows shown           : 20 of 60 
## 
##      Flavor       Packaging      Light     Organic Prediction
##  Strawberry Homemade waffle    Low fat     Organic     10.200
##  Strawberry            Cone    Low fat     Organic     10.200
##       Mango Homemade waffle    Low fat     Organic     10.200
##       Mango            Cone    Low fat     Organic     10.200
##  Strawberry Homemade waffle No low fat     Organic      9.200
##  Strawberry            Cone No low fat     Organic      9.200
##       Mango Homemade waffle No low fat     Organic      9.200
##       Mango            Cone No low fat     Organic      9.200
##  Strawberry Homemade waffle    Low fat Not organic      8.800
##  Strawberry            Cone    Low fat Not organic      8.800
##       Mango Homemade waffle    Low fat Not organic      8.800
##       Mango            Cone    Low fat Not organic      8.800
##     Vanilla Homemade waffle    Low fat     Organic      8.700
##     Vanilla            Cone    Low fat     Organic      8.700
##  Strawberry            Pint    Low fat     Organic      8.200
##       Mango            Pint    Low fat     Organic      8.200
##  Strawberry Homemade waffle No low fat Not organic      7.800
##  Strawberry            Cone No low fat Not organic      7.800
##       Mango Homemade waffle No low fat Not organic      7.800
##       Mango            Cone No low fat Not organic      7.800

Same conclusion as that from the previous section: this person would enjoy a low fat, organic, mango or strawberry ice cream in a cone or one a homemade waffle the most.

8.4 Many respondents

8.4.1 Estimate part-worths and importance weights

Now, let’s carry out the conjoint analysis on the full dataset to get an idea of which ice creams the 15 respondents, on average, liked the most and how important each attribute is:

conjoint_allrespondents <- conjoint(icecream, rvar = "rating", evar = c("Flavor","Packaging","Light","Organic")) # same as before, but different dataset.

summary(conjoint_allrespondents) 
## Conjoint analysis
## Data                 : icecream 
## Response variable    : rating 
## Explanatory variables: Flavor, Packaging, Light, Organic 
## 
## Conjoint part-worths:
##    Attributes          Levels     PW
##  Flavor       Chocolate        0.000
##  Flavor       Mango            1.522
##  Flavor       Raspberry        0.522
##  Flavor       Strawberry       0.767
##  Flavor       Vanilla          1.389
##  Packaging    Cone             0.000
##  Packaging    Homemade waffle -0.244
##  Packaging    Pint            -0.100
##  Light        Low fat          0.000
##  Light        No low fat       0.478
##  Organic      Not organic      0.000
##  Organic      Organic          0.307
##  Base utility ~                4.358
## 
## Conjoint importance weights:
##  Attributes    IW
##   Flavor    0.597
##   Packaging 0.096
##   Light     0.187
##   Organic   0.120
## 
## Conjoint regression results:
## 
##                            coefficient
##  (Intercept)                     4.358
##  Flavor|Mango                    1.522
##  Flavor|Raspberry                0.522
##  Flavor|Strawberry               0.767
##  Flavor|Vanilla                  1.389
##  Packaging|Homemade waffle      -0.244
##  Packaging|Pint                 -0.100
##  Light|No low fat                0.478
##  Organic|Organic                 0.307

Flavor is by far the most important attribute. Let’s plot these results:

plot(conjoint_allrespondents)

From this, we predict that, on average, people would most like an organic, non low fat, mango ice cream in a cone.

The importance weights tell us how strongly each attribute determines the average rating of an ice cream. Flavor is the most important attribute and packaging is the least important attribute. This respondent’s rating is determined for 59.7 percent by flavor and for 9.6 percent by packaging.

8.4.2 Profiles: predicted utilities

Let’s predict the ratings of all possible ice creams:

predict(conjoint_allrespondents, profiles.all) %>% # check previous sections for profiles.all
  arrange(desc(Prediction)) # show the ice creams with the highest predicted rating on top
## Conjoint Analysis
## Data                 : icecream 
## Response variable    : rating 
## Explanatory variables: Flavor, Packaging, Light, Organic 
## Prediction dataset   : profiles.all 
## Rows shown           : 20 of 60 
## 
##      Flavor       Packaging      Light     Organic Prediction
##       Mango            Cone No low fat     Organic      6.664
##       Mango            Pint No low fat     Organic      6.564
##     Vanilla            Cone No low fat     Organic      6.531
##     Vanilla            Pint No low fat     Organic      6.431
##       Mango Homemade waffle No low fat     Organic      6.420
##       Mango            Cone No low fat Not organic      6.358
##     Vanilla Homemade waffle No low fat     Organic      6.287
##       Mango            Pint No low fat Not organic      6.258
##     Vanilla            Cone No low fat Not organic      6.224
##       Mango            Cone    Low fat     Organic      6.187
##     Vanilla            Pint No low fat Not organic      6.124
##       Mango Homemade waffle No low fat Not organic      6.113
##       Mango            Pint    Low fat     Organic      6.087
##     Vanilla            Cone    Low fat     Organic      6.053
##     Vanilla Homemade waffle No low fat Not organic      5.980
##     Vanilla            Pint    Low fat     Organic      5.953
##       Mango Homemade waffle    Low fat     Organic      5.942
##  Strawberry            Cone No low fat     Organic      5.909
##       Mango            Cone    Low fat Not organic      5.880
##     Vanilla Homemade waffle    Low fat     Organic      5.809

Same conclusions as before: we predict that, on average, people would most like an organic, non low fat, mango ice cream in a cone.

8.5 Market simulation

Say we have created a small number of ice creams and we want to estimate the market share of each of those ice creams. Let’s say we have selected the following four profiles:

# use slice() to select rows
market_profiles <- profiles.all %>% 
  slice(c(4, 16, 23, 38)) # from profiles.all, select rows 4, 16, 23, 38 as the four profiles

market_profiles
##       Flavor       Packaging      Light     Organic
## 1 Strawberry            Cone    Low fat Not organic
## 2  Chocolate            Cone No low fat Not organic
## 3  Raspberry Homemade waffle No low fat Not organic
## 4  Raspberry Homemade waffle    Low fat     Organic

We already know how to estimate which ice cream will be liked the most:

conjoint_allrespondents <- conjoint(icecream, rvar = "rating", evar = c("Flavor","Packaging","Light","Organic"))

predict(conjoint_allrespondents, market_profiles) %>%
  arrange(desc(Prediction))
## Conjoint Analysis
## Data                 : icecream 
## Response variable    : rating 
## Explanatory variables: Flavor, Packaging, Light, Organic 
## Prediction dataset   : market_profiles 
## 
##      Flavor       Packaging      Light     Organic Prediction
##  Strawberry            Cone    Low fat Not organic      5.124
##   Raspberry Homemade waffle No low fat Not organic      5.113
##   Raspberry Homemade waffle    Low fat     Organic      4.942
##   Chocolate            Cone No low fat Not organic      4.836

The low fat, non-organic strawberry ice cream in a cone has the highest predicted rating across all respondents. But this doesn’t tell us what the market share of each of the four profiles will be. For this, we need to know, for each participant, which profile he or she would choose. In other words, we need to predict the ratings for each individual separately:

# same model as before, but now add by = "respondent"
conjoint_perrespondent <- conjoint(icecream, rvar = "rating", evar = c("Flavor","Packaging","Light","Organic"), by = "respondent")

predict(conjoint_perrespondent, market_profiles) %>% 
  arrange(respondent, desc(Prediction)) # sort by respondent and then by predicted rating
## Conjoint Analysis
## Data                 : icecream 
## Response variable    : rating 
## Explanatory variables: Flavor, Packaging, Light, Organic 
## Prediction dataset   : market_profiles 
## Rows shown           : 20 of 60 
## 
##     respondent     Flavor       Packaging      Light     Organic Prediction
##   Individual 1 Strawberry            Cone    Low fat Not organic      8.800
##   Individual 1  Raspberry Homemade waffle    Low fat     Organic      3.700
##   Individual 1  Chocolate            Cone No low fat Not organic      2.800
##   Individual 1  Raspberry Homemade waffle No low fat Not organic      1.300
##  Individual 10  Raspberry Homemade waffle No low fat Not organic      9.950
##  Individual 10  Raspberry Homemade waffle    Low fat     Organic      8.967
##  Individual 10  Chocolate            Cone No low fat Not organic      5.367
##  Individual 10 Strawberry            Cone    Low fat Not organic      2.033
##  Individual 11 Strawberry            Cone    Low fat Not organic      5.800
##  Individual 11  Raspberry Homemade waffle    Low fat     Organic      5.200
##  Individual 11  Chocolate            Cone No low fat Not organic      3.800
##  Individual 11  Raspberry Homemade waffle No low fat Not organic      2.800
##  Individual 12  Raspberry Homemade waffle No low fat Not organic      9.600
##  Individual 12  Raspberry Homemade waffle    Low fat     Organic      7.733
##  Individual 12  Chocolate            Cone No low fat Not organic      5.933
##  Individual 12 Strawberry            Cone    Low fat Not organic      3.267
##  Individual 13  Raspberry Homemade waffle No low fat Not organic      6.550
##  Individual 13  Raspberry Homemade waffle    Low fat     Organic      6.200
##  Individual 13  Chocolate            Cone No low fat Not organic      5.300
##  Individual 13 Strawberry            Cone    Low fat Not organic      1.300

Let’s retain for each individual only his or her highest rated profile. We can do this by grouping per respondent and by adding a variable named ranking that will tell us the ranking of profiles, based on predicted rating, for every respondent:

highest_rated <- predict(conjoint_perrespondent, market_profiles) %>% 
  group_by(respondent) %>% 
  mutate(ranking = rank(Prediction))

# have a look
highest_rated %>% 
  arrange(respondent, ranking)
## # A tibble: 60 × 7
## # Groups:   respondent [15]
##    respondent    Flavor     Packaging       Light      Organic     Prediction ranking
##    <chr>         <fct>      <fct>           <fct>      <fct>            <dbl>   <dbl>
##  1 Individual 1  Raspberry  Homemade waffle No low fat Not organic       1.30       1
##  2 Individual 1  Chocolate  Cone            No low fat Not organic       2.8        2
##  3 Individual 1  Raspberry  Homemade waffle Low fat    Organic           3.7        3
##  4 Individual 1  Strawberry Cone            Low fat    Not organic       8.8        4
##  5 Individual 10 Strawberry Cone            Low fat    Not organic       2.03       1
##  6 Individual 10 Chocolate  Cone            No low fat Not organic       5.37       2
##  7 Individual 10 Raspberry  Homemade waffle Low fat    Organic           8.97       3
##  8 Individual 10 Raspberry  Homemade waffle No low fat Not organic       9.95       4
##  9 Individual 11 Raspberry  Homemade waffle No low fat Not organic       2.80       1
## 10 Individual 11 Chocolate  Cone            No low fat Not organic       3.8        2
## # … with 50 more rows
# we need to retain only the highest ranked ice cream
highest_rated <- highest_rated %>% 
  arrange(respondent, ranking) %>% 
  filter(ranking == 4)

highest_rated
## # A tibble: 15 × 7
## # Groups:   respondent [15]
##    respondent    Flavor     Packaging       Light      Organic     Prediction ranking
##    <chr>         <fct>      <fct>           <fct>      <fct>            <dbl>   <dbl>
##  1 Individual 1  Strawberry Cone            Low fat    Not organic       8.8        4
##  2 Individual 10 Raspberry  Homemade waffle No low fat Not organic       9.95       4
##  3 Individual 11 Strawberry Cone            Low fat    Not organic       5.8        4
##  4 Individual 12 Raspberry  Homemade waffle No low fat Not organic       9.6        4
##  5 Individual 13 Raspberry  Homemade waffle No low fat Not organic       6.55       4
##  6 Individual 14 Raspberry  Homemade waffle No low fat Not organic       9.8        4
##  7 Individual 15 Strawberry Cone            Low fat    Not organic       8.53       4
##  8 Individual 2  Strawberry Cone            Low fat    Not organic       9.63       4
##  9 Individual 3  Chocolate  Cone            No low fat Not organic       5.57       4
## 10 Individual 4  Raspberry  Homemade waffle Low fat    Organic           4.2        4
## 11 Individual 5  Strawberry Cone            Low fat    Not organic       4.93       4
## 12 Individual 6  Raspberry  Homemade waffle Low fat    Organic           9.4        4
## 13 Individual 7  Strawberry Cone            Low fat    Not organic       9.17       4
## 14 Individual 8  Chocolate  Cone            No low fat Not organic       4.93       4
## 15 Individual 9  Strawberry Cone            Low fat    Not organic       7.87       4

We can now estimate the market share:

market_share <- highest_rated %>% 
  group_by(Flavor, Packaging, Light, Organic) %>% 
  summarize(count = n()) %>% 
  arrange(desc(count))
## `summarise()` has grouped output by 'Flavor', 'Packaging', 'Light'. You can override using the `.groups`
## argument.
market_share
## # A tibble: 4 × 5
## # Groups:   Flavor, Packaging, Light [4]
##   Flavor     Packaging       Light      Organic     count
##   <fct>      <fct>           <fct>      <fct>       <int>
## 1 Strawberry Cone            Low fat    Not organic     7
## 2 Raspberry  Homemade waffle No low fat Not organic     4
## 3 Chocolate  Cone            No low fat Not organic     2
## 4 Raspberry  Homemade waffle Low fat    Organic         2

We see that the strawberry, cone, low fat, not organic ice cream is favored by 7 out of 15 respondents, the raspberry, homemade waffle, no low fat, not organic ice cream is favored by 4 out of 15 respondents, and so on.