title: Linear regression with product of factor and independent variable
body: <p>I am try to estimate a demand model:</p>
  
  <pre><code>d_t^k = a_t - b^k p_t^k + e_t^k
  </code></pre>
  
  <p>The indices <code>t</code> are for week number, <code>k</code> are for product number. The demand for each product <code>d_t^k</code> depends on the general seasonality that is shared by all the products <code>a_t</code>, and is a affine function of the price of the product in that week <code>p_t^k</code>, plus some normal random error <code>e_t^k</code>.</p>
  
  <p>However, if I use the following <code>lm</code> function call, it gives me a single coefficient <code>b</code> for <code>price</code>, when what I want is one coefficient per product <code>b^k</code> for <code>price^k</code>.</p>
  
  <pre><code>lm(demand ~ factor(week) + price, data = df)
  </code></pre>
  
  <p>What is the right way to express the model?</p>
  
  <pre><code>lm(demand ~ factor(week) + factor(product) * price, data = df)
  </code></pre>
  
  <p>I am guessing that the above would work, and it but I can't find any documentation that tells me what is going on there.</p>
  
  <p>As a concrete example, I have the following code that runs, on a slightly different demand model
       d_t^k = a_t + a^k - b^k p_t^k + e_t^k</p>
  
  <pre><code># Generate fake prices and sales, and estimate the coefficients of
  # the demand model.
  
  number.of.items &lt;- 20 # Must be a multiple of 4
  number.of.weeks &lt;- 5
  coeff.item.min &lt;- 300
  coeff.item.max &lt;- 500
  coeff.price.min &lt;- 1.4
  coeff.price.max &lt;- 2
  normal.sd &lt;- 40
  set.seed(200)
  
  # Generate random coefficients for the items
  coeff.item &lt;- runif(number.of.items, coeff.item.min, coeff.item.max)
  coeff.price &lt;- runif(number.of.items, coeff.price.min, coeff.price.max)
  coeff.week &lt;- 50 * 1:number.of.weeks
  
  # Row is item, column is week
  week.id.matrix &lt;- outer(rep(1, number.of.items), 1:number.of.weeks)
  item.id.matrix &lt;- outer(1:number.of.items, rep(1, number.of.weeks))
  price.matrix &lt;- rbind(
    outer(rep(1, number.of.items / 4), c(100, 100, 90, 90, 80)),
    outer(rep(1, number.of.items / 4), c(100, 90, 90, 80, 60)),
    outer(rep(1, number.of.items / 4), c(100, 85, 85, 60, 60)),
    outer(rep(1, number.of.items / 4), c(100, 75, 60, 45, 45))
  )
  coeff.week.matrix &lt;- outer(rep(1, number.of.items), coeff.week)
  coeff.price.matrix &lt;- outer(coeff.price, rep(1, number.of.weeks))
  coeff.item.matrix &lt;- outer(coeff.item, rep(1, number.of.weeks))
  sales.matrix &lt;- coeff.week.matrix +
    coeff.item.matrix -
    coeff.price.matrix * price.matrix +
    matrix(rnorm(number.of.weeks * number.of.items, 0, normal.sd),
           number.of.items, number.of.weeks)
  
  
  df &lt;- data.frame(item = factor(as.vector(item.id.matrix)),
                   week = factor(as.vector(week.id.matrix)),
                   price = as.vector(price.matrix),
                   sales = as.vector(sales.matrix))
  
  model &lt;- lm(sales ~ week + item + price, data = df)
  model &lt;- lm(sales ~ week + item + factor(item) * price, data = df)
  
  print(summary(model))
  </code></pre>