An improved demand curve for analysis of food or drug consumption in behavioral experiments

The incorporation of microeconomics concepts into studies using self-administration procedures has provided critical insights into the factors that influence consumption of a wide range of food and drug reinforcers. In particular, the fitting of demand curves to consumption data provides a powerful analytic tool for computing objective metrics of behavior that can be compared across a wide range of reward types in both human and animal experiments. The results of these analyses depend crucially on the mathematical form used to fit the data. The most common choice is an exponential form proposed by Hursh and Silberberg, which is widely used and has provided fundamental insights into relationships between cost and consumption, but it also has some disadvantages. In this paper, we first briefly review the use of demand curves to quantify the motivating effects of food and drugs, then we describe the current methodology and highlight some potential issues that arise in its application. To address these issues, we propose a new mathematical framework for the analysis of consumption data, including a new functional form for the demand curve. We show that this proposed form gives good fits to data for a range of different reinforcers and experimental protocols, while allowing for straightforward calculation of key metrics of demand, including preferred consumption level, maximum response, price at maximum response, and price elasticity of demand. We provide software implementing our entire analysis pipeline, including data fits, data visualization, and the calculation of demand metrics. Electronic supplementary material The online version of this article (10.1007/s00213-020-05491-2) contains supplementary material, which is available to authorized users.

Example of the format of the input data. The first column (column A) represents prices, which can be in any units. (Ours are in responses per milligram.) Second and subsequent columns, of which there can be any number, represent responses at each price point for separate animals, sessions, or data sets. In this case the file has columns for three different sessions (columns B, C, and D). Our responses are whole numbers, since they represent lever presses by individual animals, but one can also use responses averaged over several animals or sessions, in which case the values need not be whole numbers. When complete, the spreadsheet should be saved in CSV (comma-separated value) format with commas as separators between the fields.

Data input
The program takes input data in the form of prices and responses. It can handle an arbitrary number of price points in a single analysis and can analyze data from multiple animals or multiple sessions in a single run. Data should be prepared in a spreadsheet as shown in Fig. S1. The first column of the sheet contains the prices, in any units you choose. Prices can be in any order-they need not be in increasing (or decreasing) order, though they can be. There must be at least four different prices for the program to work correctly (i.e., at least four rows in the spreadsheet), since there are four parameters in the fitted demand curve. (The number of data points for any fit can never be less than the number of parameters.) The second and subsequent columns contain the response at each price in terms of the amount of work (e.g., number of lever presses) done in experimental sessions, with one column for each session or data set. There can be just a single session (for a total of two columns-prices and responses) or many (for a total of n + 1 columns if there are n sessions). There should be no blank cells, nor empty rows or columns, in the spreadsheet, except for the unused rows and columns below and to the right of the data. (If you wish to analyze data from experiments using different numbers of price points then you will have to use separate spreadsheets.) The spreadsheet should be saved in CSV (comma-separated value) format, using commas as separators between the values and the file extension ".csv". (Note that CSV files can be saved with spaces as separators, but this should be avoided as it will not work with our program.) When using Microsoft Excel, for instance, saving as a CSV file is a standard option under the "Save as" menu item; any of the sub-formats listed there (Macintosh, MS-DOS, or CSV) will work. An example input file, called example.csv, is included in the accompanying online materials.

Running the program
Windows: On an appropriately configured Windows system it will be possible to run the program from a command prompt window (also known as a "DOS window"), by changing to the folder where the program file resides and typing either "py demand.py" or "python demand.py" into the command window (depending on how the computer is set up). Alternatively, the program can be run inside a Python development environment such as Jupyter, Idle, or Spyder. The latter are all included, for instance, in the Anaconda distribution mentioned above. When Anaconda is started it will display a screen offering a choice of environments for use. Start the environment of choice by double-clicking on its launch icon, then load the program demand.py and run it. Specific procedure will depend on which environment you use. See the video tutorial for an example using the Spyder environment.
OSX: On a Mac one can normally open a command window and type "python demand.py" to run the program, or use any of the several available Python development environments-see the instructions for Windows users above.
Linux: Under Linux one can run the program from the command line with the command "python demand.py" or from within a development environment.

Using the program
When first run, the program will ask for the name of the input data file. Type in the name of the CSV file containing your data. (The name is case-sensitive, so take care with capitalization.) The file extension ".csv" at the end of the name is optional and can be omitted. The file name can also be provided to the program as a command-line argument when the program is run. For instance, under Windows one might type "py demand.py example.csv" and the program would use the data file example.csv. This is a convenient feature when running the program in batch mode (i.e., unattended).
Once the file name is entered, the program will perform the analysis. It works by computing consumption levels from the response data then performing a nonlinear least-squares fit of the logarithms of the consumption values to Eq. (21) from the main paper. The program automatically calculates parameter values and a range of other quantities, and takes appropriate precautions so that, for instance, parameter values cannot become infinite.
The output of a typical run of the program looks like this: Data read from file example.csv Price points: 10 Curves: 3 Analyzing curve 1 Analyzing curve 2 Analyzing curve 3 Fig. S2 Example of the output spreadsheet generated by the program. Columns contain the parameters Q 0 , P 0 , a, and b of the fitted demand curves, plus the derived values Rmax, Pmax, and Pmax ("Normalized Pmax"), as indicated, and there is one row of the spreadsheet for each data set in the input file.
The program gives a summary of the data it found in the input file (number of price points and number of data sets), then lists the demand curves one by one as it analyzes them. The program may also print out cautionary messages if it believes there are potential problems with the data. For instance, if the fitted value of Q 0 lies well outside the range of observed consumption it will print a message like this: Caution: Q0 = 880 is substantially outside the data range [2.5 to 140] This could be an indication that the experiment failed to probe the salient portion of the demand curve near the turning point at which demand falls off.
When the program finishes, which typically takes a few seconds, it will produce a set of output files in the same folder. First, there will be an output data file. If the input file was called example.csv, the output file will be called example params.csv. This is a CSV spreadsheet containing the best fit values of the parameters Q 0 , P 0 , a, and b for each session in the input file, plus the values of the derived quantities Rmax, Pmax, and Pmax. This file can be opened in Microsoft Excel, Google Docs, or any similar spreadsheet program. There is one row of the file for each session, in the same order as the columns of the input file, so that the row for curve 1 corresponds to data in column B of the input file, curve 2 to data in column C, and so forth. An example output file is shown in Fig. S2.
It is a good idea before using the numerical results of any of the fits to inspect the corresponding figures to make sure that the fit is a reasonable one. If the data fluctuate a lot, or if the experiment fails to probe the correct price range, then the fit may be a poor one. In cases where the data are entirely unlike the expected demand-curve form of plateau-plus-decline, the fit may fail and the fitted curve will not resemble the data points. Some thought may be needed to interpret the results of the procedure in any specific case. Rmax is the highest value of the revenue curve and Pmax is the price at which that highest value occurs. In this case we find Rmax = 41.6 responses and Pmax = 17.3 responses per milligram.

Initial parameter values
In performing a fit, the program works by guessing approximate initial values of the four parameters Q 0 , P 0 , a, and b and then adjusting them repeatedly until a good fit is achieved. While the program normally makes sensible initial guesses for the parameters, there may be occasional instances, particularly with poor-quality data, where the process fails because the initial guesses are too far from the correct values, and the program will not generate a sensible fit. For advanced users, we incorporate an additional feature in the program that allows the user to choose the starting values themselves, overriding the values chosen by the program. To use this feature the program should be started from a command line or DOS window and the desired starting values of Q 0 , P 0 , a, and b should be given, in that order, on the command line, after the name of the CSV file. Thus, for instance, on a suitably configured Windows system one might type the line "py demand.py example.csv 3.5 30 3 2". This tells the program to read data from the file example.csv and initially to set the parameters (for all sessions) to the values Q 0 = 3.5, P 0 = 30, a = 3, and b = 2. In some cases this will allow the program to find a fit to the data that it would otherwise not be able to find.
How should one go about choosing suitable starting values for the parameters when using this feature? In the case of Q 0 , a plot of consumption against price, as in the left panel of Fig. S3, is often enough to make a useful estimate-one simply looks for the height of the plateau on the left-hand side of the figure. In  In the most difficult cases it may be necessary to run the program more than once with the same data and different starting parameters to find values that work well.

Additional analysis
Figures 1 and 2 in the paper show fits of the same cocaine self-administration data to the demand curve form we propose and to the exponential form of Hursh and Silberberg (2008). In Fig. S4 we show a further comparison of fits to these two forms. The figure is a modified version of Fig. 5 from the paper, showing the same data for cocaine self-administration by four different male rats and the same fits to the form we propose (blue curves). But now we also add best fits to the exponential form, with the parameter k once again set equal to the maximum range of the logarithm of the data over all sessions, which in this case results in k = 6.62. As the figure shows, the fit to the exponential form is about as good as to our proposed form in two cases (b and d), a little worse in one case (a), and significantly poorer in the last case (c). Figure 5 in the paper shows fits of our proposed demand curve form to data for cocaine self-administration by four male rats. The data shown are relatively Cocaine self-administration data for four more male rats, taken from the same experiment as Fig. S4, but this time deliberately picking data of poorer quality, in order to test our approach. As the figure shows, our proposed demand curve form, as implemented in the software described here, is still able to find convincing fits to the data. (Previously unpublished data kindly provided by C. Carr and T. E. Robinson.) clean examples in which the demand roughly follows the expected plateau-plusdecline form. In every experiment, however, there are always some sessions in which animals do not behave as expected and the data are less clean-sometimes much less so. In Fig. S5 we show four more examples from the same set of cocaine self-administration experiments, but in this case we have deliberately chosen data of poorer quality, showing the largest deviation from the expected behavior. As the figure shows, our procedure (implemented in the software described above) is still able to find convincing fits to the data, allowing us to extract values for parameters such as Pmax or Rmax.