Dog food preference experiment:
Do dogs prefer pricier foods?

The Faigons, June 2012
Download the Dog-Food preference chart script

1. The problem:

Every week we go and buy food for our dog. Julie, our 5.5 year old yellow lab is a very picky eater who doesn't like dog food very much. She greatly prefers human food. We have spent a lot of money over the years trying different kinds of dog food. Some of it was pretty expensive, but we never made the price a factor in what to buy. We wanted Julie to have the best food. We wanted her to be both healthy and happy.

The more expensive food, so "the web" told us, has less filler, and more healthy ingredients. This may be so, but if Julie herself could talk and tell us which food she prefers, we felt we would have another valuable data-point.

We decided to do a simple experiment and expose Julie at the same time to different kinds of food so she can tell us which one she prefers. As a twist to make the experiment more interesting we decided to record not just her preference, but also the price-per-pound for each food we give her.

2. The experiment:

We bought 4 brands of food. Each meal was divided in 4-parts and served on 4 separate plates, one plate per brand.

Preparing for the 1st experiment: the 4 brands in 4 plates
Preparing for the 1st experiment: the 4 brands in 4 plates

1st experiment: Julie checks the food
1st experiment: Julie checks the food
1st experiment: Julie eats in her preferred order
1st experiment: Julie eats in her preferred order
1st experiment: Julie eats in her preferred order
1st experiment: Julie eats in her preferred order

Before each meal we shuffled the order of the plates randomly and wrote down the order in which Julie decided to eat them: From 4 (most preferred, eaten first) to 1 (least-preferred, eaten last) Note that the numeric labels (1,2,3,4) are identifiers for the brands, there's no relation between them and the 'preference' order although both use the same 4 numbers.

2nd experiment: bags gone, order shuffled
2nd experiment: bags gone, order shuffled
2nd experiment: Julie eats in her preferred order
2nd experiment: Julie eats in her preferred order
2nd experiment: Julie eats in her preferred order
2nd experiment: Julie eats in her preferred order
4th experiment: 1 and 2 are first to be eaten
4th experiment: 1 and 2 are first to be eaten

It is hard to see this in the photo because Julie's head is blocking the view of 3 of the plates (labeled 1, 4, and 3). But once again, Julie started from the one labeled '1', even though it was in the middle, preferring to continue with the one labeled '2' and then move to the left for the last two plates (4, and 3).

4th experiment: 1 and 2 are first to be eaten
4th experiment: 1 and 2 are first to be eaten
5th experiment: still deciding where to start
5th experiment: still deciding where to start
5th experiment: still deciding where to start
5th experiment: still deciding where to start

After 5 meals we had this table. The last number is the mean of the preference-scores across all experiments:

Brand,weight,price,meal1,meal2,meal3,meal4,meal5,preference
"1: Pedigree",4.4,6.99,4,4,3,4,4,3.8
"2: Iams",6.1,13.49,3,3,4,3,1,2.8
"3: Eukanuba",4.0,14.99,2,2,2,1,3,2.0
"4: Wellness",4.0,19.99,1,1,3,2,1,1.6

Here's the experiment raw data, rendered in a more readable way:

3. The Chart (click to enlarge):

Using Hadley Wickham's wonderful R/ggplot2 library we generated the following chart from the data:
Our dog food preference chart: preference by price-per-pound
The 1000 word story in a single chart

4. Conclusions, disclaimers and thoughts

We were surprised by the results and by the consistency our dog demonstrated across the experiments despite us shuffling the order of plates between experiments.

We started this experiment with no preconceived notions and no hope for any specific winner. We had no stake in any specific result nor any preference for any of the foods we tried.

To make the results more statistically significant, we should have done a larger number of experiments, but we prefer the Bayesian approach (as opposed to frequentist approach) to statistics. Given what we knew, at a certain point the results were just too obvious and consistent for us, so we stopped. Julie has told us in no ambiguous terms what her preferences are. (see this example for the case of "low N, strong effect, strong support")

We welcome any criticism and suggestions for improvements. We also encourage other people to run their own experiments, with more brands of food, and publish them on the web.

The experiment doesn't say which food is healthier. It only tells us which one is preferred by the dog herself.

Here are some of our observations:

Other thoughts

Dogs sense of smell is known to be much better than that of humans. According to Wikipedia, it has been estimated that dogs, in general, have an olfactory sense ranging from one hundred thousand to one million times more sensitive than a human's. In some dog breeds, such as bloodhounds, the olfactory sense may be up to 100 million times greater than a human's.

The sense of smell seems to have taken a major part in our Dog's decision to follow an order. Julie has very poor eye-sight and she always sniffs her food before she eats.

5. Charting Code (R/ggplot source)

#!/usr/bin/r -pi
#
# script to generate chart for dog-food experiment
#

# -- where to look for R libraries
.libPaths(c('~/local/lib/R',
             '/usr/lib/R/library',
             '/usr/lib/R/site-library'
))


#
# require needed libraries:
#
suppressPackageStartupMessages(library(ggplot2))
# for date breaks/formatting functions
suppressPackageStartupMessages(library(scales))

#
# Graphical constants
#   Default chart width and height, resolution, font-size
#   (ggplot saves too big files by default)
#
golden.ratio = 1.61803399887
W = 4.0
H = W / golden.ratio
DPI = 200
FONTSIZE=8

#
# Theme definitions
#
title.theme = theme_text(family="FreeSans", face="bold.italic", size=FONTSIZE)
y.label.theme = theme_text(family="FreeSans", face="bold.italic",
                           size=FONTSIZE-2, angle=90)
x.label.theme = theme_text(family="FreeSans", face="bold.italic",
                           size=FONTSIZE-2)
x.axis.theme = theme_text(family="FreeSans", face="bold",
                          size=FONTSIZE-2, colour="grey50")
y.axis.theme = theme_text(family="FreeSans", face="bold",
                          size=FONTSIZE-2, colour="grey50")

#
# generate_chart
#   Generic function to generate one (Y = f(time)) time-series chart
#   with a LOESS smoothed line, and monthly x-axis labeling
#
generate_chart <- function(
    data=d,
    x,
    y,
    title='The title',
    ylab='The Y-axis label',
    xlab='The X-axis label',
    file='thechart.png'
) {
    the.aes <- eval(substitute(aes(x, y),
                list(x = substitute(x), y = substitute(y))))

    ggplot(data=d, the.aes) +
    geom_smooth(method='loess') +
    geom_point(aes(color=Brand), pch=20, cex=5) +
    opts(title=title,
         plot.title=title.theme,
         axis.title.y=y.label.theme,
         axis.title.x=x.label.theme,
         axis.text.x=x.axis.theme,
         axis.text.y=y.axis.theme
    ) +
    scale_x_continuous(xlab,
                     breaks=c(1,2,3,4,5),
                     labels=c('$1.0','$2.0','$3.0','$4.0','$5.0')) +
    scale_y_continuous(ylab,
                     breaks=c(2.0,2.5,3.0,3.5,4.0),
                     labels=c('2.0','2.5','3.0','3.5','4.0'))

    ggsave(file=file, width=W, height=H, dpi=DPI)
}

#
# main
#
if (! exists('argv') || is.null(argv) || (length(argv) < 1)) {
    argv <- c('dogpref.csv')
}
csvfile <- argv[1]

#
# -- read the CSV data into data-frame 'd'
#
d <- read.csv(csvfile, h=T)

#
# Calculate new columns from existing ones and convert date type
#
d <- transform(d,
    price.per.pound=price/weight
)

#
# Generate the price-per-pound vs dog-preference chart
#
generate_chart(
        data=d,
        x=price.per.pound,
        y=preference,
        title='Dog food Preference vs Price/Pound',
        ylab='Preference (Higher is preferred)',
        xlab='Price / Pound',
        file='dogpref.png'
)

warnings()
R (littler) code to generate the above chart