Note that there are some explanatory texts on larger screens.

plurals
  1. POInterpolate product attributes
    primarykey
    data
    text
    <p>I have a set of data from a set of <a href="http://en.wikipedia.org/wiki/Discrete_choice">discrete choice tasks</a> which included two alternatives with three attributes (brand, price, performance). From this data, I have taken 1000 draws from the posterior distribution which I'll then use to calculate utility and eventually preference share for each individual and each draw. </p> <p>Price and performance were tested at discrete levels (-.2, 0, .2) and (-.25, 0, .25) respectively. I need to be able to interpolate utility between attribute levels tested. Let's assume for now that a linear interpolation is a reasonable thing to do statistically. In other words, what is the most efficient way to interpolate the utility for price if I wanted to test a scenario with price @ 10% lower? I have not been able to think of a slick or efficient way to do the interpolation. I've resorted to an mapply() approach with the mdply function from plyr</p> <p>Here's some data and my current approach:</p> <pre><code>library(plyr) #draws from posterior, 2 respondents, 2 draws each draw &lt;- list(structure(c(-2.403, -2.295, 3.198, 1.378, 0.159, 1.531, 1.567, -1.716, -4.244, 0.819, -1.121, -0.622, 1.519, 1.731, -1.779, 2.84), .Dim = c(2L, 8L), .Dimnames = list(NULL, c("brand_1", "brand_2", "price_1", "price_2", "price_3", "perf_1", "perf_2", "perf_3"))), structure(c(-4.794, -2.147, -1.912, 0.241, 0.084, 0.31, 0.093, -0.249, 0.054, -0.042, 0.248, -0.737, -1.775, 1.803, 0.73, -0.505), .Dim = c(2L, 8L), .Dimnames = list(NULL, c("brand_1", "brand_2", "price_1", "price_2", "price_3", "perf_1", "perf_2", "perf_3")))) #define attributes for each brand: brand constant, price, performance b1 &lt;- c(1, .15, .25) b2 &lt;- c(2, .1, .2) #Create data.frame out of attribute lists. Wil use mdply to go through each interpolateCombos &lt;- data.frame(xout = c(b1,b2), atts = rep(c("Brand", "Price", "Performance"), 2), i = rep(1:2, each = 3), stringsAsFactors = FALSE) #Find point along line. Tried approx(), but too slow findInt &lt;- function(x1,x2,y1,y2,reqx) { range &lt;- x2 - x1 diff &lt;- reqx - x1 out &lt;- y1 + ((y2 - y1)/range) * diff return(out) } calcInterpolate &lt;- function(xout, atts, i){ if (atts == "Brand") { breaks &lt;- 1:2 cols &lt;- 1:2 } else if (atts == "Price"){ breaks &lt;- c(-.2, 0, .2) cols &lt;- 3:5 } else { breaks &lt;- c(-.25, 0, .25) cols &lt;- 6:8 } utils &lt;- draw[[i]][, cols] if (atts == "Brand" | xout %in% breaks){ #Brand can't be interpolated or if level matches a break out &lt;- data.frame(out = utils[, match(xout, breaks)]) } else{ #Must interpolate mi &lt;- min(which(breaks &lt;= xout)) ma &lt;- max(which(breaks &gt;= xout)) out &lt;- data.frame(out = findInt(breaks[mi], breaks[ma], utils[, mi], utils[,ma], xout)) } out$draw &lt;- 1:nrow(utils) return(out) } out &lt;- mdply(interpolateCombos, calcInterpolate) </code></pre> <p>To provide context on what I'm trying to accomplish without interpolating attribute levels, here's how I'd do that. Note the brands are now defined in terms of their column reference. p1 &amp; p2 refer to the product definition, u1 &amp; u2 are the utility, and s1, s2 are the preference shares for that draw. </p> <p>Any nudge in the right direction would be appreciated. My real case has 10 products with 8 attributes each. At 10k draws, my 8gb of ram are crapping out, but I can't get out of this rabbit hole I've dug myself.</p> <pre><code>p1 &lt;- c(1,2,1) p2 &lt;- c(2,1,2) FUN &lt;- function(x, p1, p2) { bases &lt;- c(0,2,5) u1 &lt;- rowSums(x[, bases + p1]) u2 &lt;- rowSums(x[, bases + p2]) sumExp &lt;- exp(u1) + exp(u2) s1 &lt;- exp(u1) / sumExp s2 &lt;- exp(u2) / sumExp return(cbind(s1,s2)) } lapply(draw, FUN, p1 = p1, p2 = p2) [[1]] s1 s2 [1,] 0.00107646039 0.9989235 [2,] 0.00009391749 0.9999061 [[2]] s1 s2 [1,] 0.299432858 0.7005671 [2,] 0.004123175 0.9958768 </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload