Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • use of mixlpred with preserve and restore to generate new variables

    Hi,

    I estimated a mixed logit model via the user written command mixlogit on the data from a discrete choice experiment (DCE).

    I need to generate the probabilities of different combinations of levels outside those included in the DCE data. For every combinations I set, I need to generate the corresponding probabilities via mixlpred as a new variable in the data editor.

    For this, I am using mixlpred and what described at page 16 and reported below:

    uk13_hole.pdf (stata.com)

    preserve
    set seed 12345
    gen rnd = runiform()
    bysort pid gid (rnd): gen alt = _n
    replace wknown = 0 if alt==1
    mixlpred p0, nrep(500)
    tabstat p0, statistics( mean)
    restore

    The code above generate p0 that can be used to produce statistics etc. as shown here. As I need to do this several times, I found particularly useful the use of "preserve" and "restore" as no data are modified. However, using mixlpred within "preserve" and "restore" does not generate any new variable as when I use mixlpred without them.

    Any help would be greatly appreciated.

    Simone



  • #2
    You could save the generated variables in a new frame. Let's call them \(\text{p0}\_1, \text{p0}\_2, \ldots, \text{p0}\_N;\; N\in \mathbb{Z}^+\).

    Code:
    *RUN THESE 3 COMMANDS ONLY ONCE AT THE START
    tempfile holding
    cap frame drop p0vars
    local i 0
    
    *EACH ITERATION START WITH
    preserve
    set seed 12345
    gen rnd = runiform()
    bysort pid gid (rnd): gen alt = _n
    replace wknown = 0 if alt==1
    mixlpred p0, nrep(500)
    tabstat p0, statistics( mean)
    local ++i
    rename p0 p0_`i'
    keep p0_`i'
    save `holding', replace
    cap frame put p0_1, into(p0vars)
    frame p0vars: merge 1:1 _n using `holding', nogen
    restore
    
    *ONCE YOU ARE DONE: VIEW VARS
    frame change p0vars
    browse
    Last edited by Andrew Musau; 09 Oct 2024, 15:14.

    Comment


    • #3
      Dear Andrew,

      Thank you very much for your post, it really helps.

      About this, below a minor modification of the code that I implemented for two reasons:

      - I need to get also alt0_i together with p0_i for each iteration
      - I need that get all the couples of (p0_i; alt0_i) in the data together with the pre-existing variables. I am writing this as from your code I could only find the new variables in the data-set.

      In the example below, the two iterations are different only for the level of one of the attributes wknown=0/1.

      It should be also noted that I removed the line: keep p0_`i' from each iteration to get the new variables into the data-set with the pre-existing ones.

      The output looks fine, but I never used frame, cap, tempfile and other things present in your code, and I have no idea if what I am doing is actually correct.

      Thanks in advance, really appreciated,

      Simone

      Code:
      *RUN THESE 3 COMMANDS ONLY ONCE AT THE START
      tempfile holding
      cap frame drop p0vars
      local i 0
      
      *EACH ITERATION START WITH
      *FIRST ITERATION
      preserve
      set seed 12345
      gen rnd = runiform()
      bysort pid gid (rnd): gen alt = _n
      replace wknown = 0 if alt==1
      mixlpred p0, nrep(500)
      tabstat p0, statistics( mean)
      local ++i
      rename p0 p0_`i'
      rename alt alt0_`i'
      save `holding', replace
      cap frame put p0_1 alt0_1, into(p0vars)
      frame p0vars: merge 1:1 _n using `holding', nogen
      restore
      
      *SECOND ITERATION
      preserve
      set seed 12345
      gen rnd = runiform()
      bysort pid gid (rnd): gen alt = _n
      replace wknown = 1 if alt==1
      mixlpred p0, nrep(500)
      tabstat p0, statistics( mean)
      local ++i
      rename p0 p0_`i'
      rename alt alt0_`i'
      save `holding', replace
      cap frame put p0_2 alt0_2, into(p0vars)
      frame p0vars: merge 1:1 _n using `holding', nogen
      restore
      
      *ONCE YOU ARE DONE: VIEW VARS
      frame change p0vars
      browse

      Comment


      • #4
        Since the only thing that changes in your iterations is the value of the variable wknown, you can use its value as the index when defining a loop. Eventually, you can merge the saved variables with the original dataset to get the combined result.

        Code:
        tempfile holding
        cap frame drop p0vars
        forval i=0/1{
            preserve
            set seed 12345
            gen rnd = runiform()    bysort pid gid (rnd): gen alt = _n
            replace wknown = `i' if alt==1
            mixlpred p0, nrep(500)
            tabstat p0, statistics( mean)
            rename (p0 alt) (p0_`i' alt0_`i')
            save `holding', replace
            keep p0_`i' alt0_`i'
            cap frame put p0_`i' alt0_`i', into(p0vars)
            frame p0vars: merge 1:1 _n using `holding', nogen
            restore
        }
        frame p0vars: save `holding', replace
        merge 1:1 _n using `holding', nogen
        frame drop p0vars
        Thus, p0_0 and alt0_0 correspond to wknown=0 and p0_1 and alt0_1 to wknown=1.

        Comment


        • #5
          Hi Andrew,

          Thank you very much for your post, it really helps.

          Actually, this made me wonder if it were possible to loop over the levels of different attributes instead of just one as in the last example.

          In the example below, it is kept all fixed apart from the two levels of wknown (0/1)and two levels of price (7/9). Thus, there are 4 combinations. For this, I created a matrix named "combinations" and I am looping over its rows.

          Code:
          matrix input combinations = (7,5,0,0,0,0\7,5,0,1,0,0\9,5,0,0,0,0\9,5,0,1,0,0)
          *LOOP
          tempfile holding
          cap frame drop p0vars
          forval i=1/4{
          preserve
          set seed 12345
          gen rnd = runiform()   
          bysort pid gid (rnd): gen alt = _n
          replace price    = combinations[`i',1] if alt==1
          replace contract = combinations[`i',2] if alt==1
          replace local    = combinations[`i',3] if alt==1
          replace wknown   = combinations[`i',4] if alt==1
          replace seasonal = combinations[`i',5] if alt==1
          replace tod      = combinations[`i',6] if alt==1
          mixlpred p0, nrep(500)
          rename (p0 alt) (p0_`i' alt0_`i')
          save `holding', replace
          keep p0_`i' alt0_`i'
          cap frame put p0_`i' alt0_`i', into(p0vars)
          frame p0vars: merge 1:1 _n using `holding', nogen
          restore
          }
          frame p0vars: save `holding', replace
          
          tabstat p0_1 if alt0_1==1, statistics( mean )
          tabstat p0_3 if alt0_3==1, statistics( mean )
          tabstat p0_2 if alt0_2==1, statistics( mean )
          tabstat p0_4 if alt0_4==1, statistics( mean )
          With this specific data-set and the estimated mixed logit model (uk13_hole.pdf (stata.com), participants do not like price and they like wknown. Thus, I would expect that:

          p1>p3
          p2>p4
          p1<p2
          p3<p4

          Checking the means of the probabilities under all the combinations, this is confirmed.

          However, as written above, I am not familiar with many parts of the code you suggested, and I have no idea if my last modification is OK.

          Thanks in advance and apologies for the very last request,

          Simone

          Comment


          • #6
            You could loop through elements of a matrix, although the conventional way to deal with this would be to define a nested loop (a loop within a loop).

            Code:
            forval i= 0/1{
                foreach j of numlist 7 9{
                    ....
                }
            }

            Comment


            • #7
              Thanks, Andrew, it worked perfectly!

              Comment

              Working...
              X