Marginal effects for binary models

For technical questions regarding estimation of single equations, systems, VARs, Factor analysis and State Space Models in EViews. General econometric questions and advice should go in the Econometric Discussions forum.

Moderators: EViews Gareth, EViews Moderator

tho_mi
Posts: 61
Joined: Sat May 12, 2012 2:41 am

Marginal effects for binary models

Postby tho_mi » Sat Mar 25, 2017 10:46 am

Hey,

I'm aware of the fact that there are already threads covering this topic, but since those are pretty old (and basically no one has used them for years) and I have some new/additional questions, I decided that opening a new one might be appropriate.

While the "theory" on the calculating itself is clear, my questions apply to the technical side:
1. Is it possible to get the dependent variables from the equation-object itself? If yes, how?
2. Is it possible to calculate column-wise means (for groups)?
3. Why hasn't this been implemented yet? I'm kinda surprised, since the calculation is pretty straightforward and I guess that people should need this regularly.

Once I've implemented the calculation I'd post the code here, so others can use it.

Thanks in advance!

Best,
Thomas

edit:
I just realized that this thread might belong to "Programming" instead of "Estimation". If a moderator agrees, could you please move the thread?

EViews Glenn
EViews Developer
Posts: 2597
Joined: Wed Oct 15, 2008 9:17 am

Re: Marginal effects for binary models

Postby EViews Glenn » Tue Mar 28, 2017 9:50 am

1. The best way to do this depends on what you want to do with the series.

2. @rmean

3. The issue is that any single calculation is straightforward, but an interface for handling all of the cases that one might want to compute is a bit less so. As this is a nonlinear expression, where you want to evaluate all of the variables matters. At-means is a common one, but there are others that are arguably considerably more useful. I can think of at least a handful of variants off the top-of-my-head, and as this has to be specified for each variable, it's a bit tricky to do something simple without limiting ourselves in the future.

That said, your point is well taken and we probably should at least do the simple at-means case in an add-in. I'll put it on the list... Thanks.

tho_mi
Posts: 61
Joined: Sat May 12, 2012 2:41 am

Re: Marginal effects for binary models

Postby tho_mi » Tue Mar 28, 2017 12:38 pm

Thanks for your answer.

I've figured out how to do it in the meantime and I've written a little script (including comments), since the script on the (AU)ROC I found was very useful (thanks btw for that!) I thought it might make sense to post it here.

It calculates the mean effects and/or the effects at the mean. Currently it only works for Logit models. Adapting it for a Probit is straightforward (just replace "@dlogistic" by "@dnorm").

It is called using something like this:

Code: Select all

run logit_marginal_effects "name_of_the_equation" "name_of_the_independent_variable" "name_of_object_with_mean_effects" "name_of_object_with_effects_at_mean"


"logit_marginal_effects" is the name of the program with the script. If only effects at the mean are needed just use an empty string for the third argument (same holds for mean effects).

Code: Select all

' This program needs four arguments, where at least one of the last two is optional:
' 1. Name of the equation
' 2. Name of the dependent variable
' 3. Name of the vector with the mean effects
' 4. Name of the vector with the effects at the mean

' Name of the equation analyzed
%eq = {%0}

' Name of the dependent variable
%dep = {%1}

' Name of the vector with the mean effects
%me = {%2}

' Name of the vector with the effects at the mean
%eatm = {%3}

' Find valid observations and restrict sample to those observations
{%eq}.makeresid _xxe
smpl if _xxe <> na

' Get the variable list of the equation and remove the dependent variable
%var_list =  {%eq}.@varlist
%indep_vars = @trim(@replace(%var_list, @upper(%dep), ""))

' Get the coefficients of the equation
coef _xxcoefs = {%eq}.@coefs

' Create a group with the independent variables and convert it to a matrix
group _xxgroup {%indep_vars}
matrix _xxindep_vars
stom(_xxgroup, _xxindep_vars)

' Get number of variables (= columns) and observations (= rows)
!num_rows = @rows(_xxindep_vars)
!num_cols = @columns(_xxindep_vars)

' Calculate mean effect
if (@isna(%me) = 0) then
   vector(!num_cols-1) {%me}
   matrix(!num_rows, !num_cols) _xxcoefsmat
   
   ' Populate a matrix with the coefficients
   for !i = 1 to !num_rows
      for !j = 1 to !num_cols
         _xxcoefsmat(!i, !j) = _xxcoefs(!j)
      next
   next
   
   ' Multiply the coefficients with the independent variables
   matrix _xxeffs = @emult(_xxcoefsmat, _xxindep_vars)
   
   vector(!num_rows) _xxprobabilities
   
   ' Calculate the probabilities for each observation
   for !i = 1 to !num_rows
      for !j = 1 to !num_cols
         _xxprobabilities(!i) = _xxprobabilities(!i) + _xxeffs(!i, !j)
      next
      
      _xxprobabilities(!i) = @dlogistic(_xxprobabilities(!i))
   next
   
   ' Get the average probability
   scalar mean_prob = @mean(probabilities)
   
   ' Calculate the average effect
   for !i = 1 to !num_cols-1
      {%me}(!i) = mean_prob * _xxcoefs(!i)
   next
   
endif

' Calculate effect at the mean
if (@isna(%eatm) = 0) then
   ' Get mean of each independent variable
   vector _xxindep_means = @cmean(_xxindep_vars)
   !meanprob = 0
   
   ' Calculate the fitted value for the average observation
   for !i = 1 to !num_cols
      !meanprob = !meanprob + _xxindep_means(!i) * _xxcoefs(!i)
   next
   
   ' Get the value of the pdf for the average observation
   !meanprob = @dlogistic(!meanprob)
   
   ' Calculate the effects at the mean
   for !i = 1 to !num_cols-1
      {%eatm}(!i) = !meanprob * _xxcoefs(!i)
   next
endif

' Clean up
smpl @all
delete _xx*

lgehrig
Posts: 15
Joined: Fri Mar 17, 2017 8:10 am

Re: Marginal effects for binary models

Postby lgehrig » Mon Mar 19, 2018 1:42 pm

Many thanks tho_mi. You saved me many lines of code.

I have used your code and found 4 small errors, 1 of which only cosmetic, 3 will prevent the script from running properly (vectors eatm and em need to be defined and should be of the appropriate length (!col_sum), "probabilities" should be "_xxprobabilities"). The cosmetic one being in your sample call to the function. Of course you mean the name of the DEPENDENT variable. Here is the corrected version now for the probit case. (again - just switch @dnorm to @dlogistic for application to logit models). Pass the arguments in the same way:

Code: Select all

run nameoftheprogram "name of the equation" "name of the dependent variable" "name of the newly created vector of mean effects" "name of the newly created vector of effects evaluated at the mean"


Code: Select all

' This program needs four arguments, where at least one of the last two is optional:
' 1. Name of the equation
' 2. Name of the dependent variable
' 3. Name of the vector with the mean effects
' 4. Name of the vector with the effects at the mean

' Name of the equation analyzed
%eq = {%0}

' Name of the dependent variable
%dep = {%1}

' Name of the vector with the mean effects
%me = {%2}

' Name of the vector with the effects at the mean
%eatm = {%3}

' Find valid observations and restrict sample to those observations
{%eq}.makeresid _xxe
smpl if _xxe <> na

' Get the variable list of the equation and remove the dependent variable
%var_list =  {%eq}.@varlist
%indep_vars = @trim(@replace(%var_list, @upper(%dep), ""))

' Get the coefficients of the equation
coef _xxcoefs = {%eq}.@coefs

' Create a group with the independent variables and convert it to a matrix
group _xxgroup {%indep_vars}
matrix _xxindep_vars
stom(_xxgroup, _xxindep_vars)

' Get number of variables (= columns) and observations (= rows)
!num_rows = @rows(_xxindep_vars)
!num_cols = @columns(_xxindep_vars)

' Calculate mean effect
if (@isna(%me) = 0) then
   matrix(!num_rows, !num_cols) _xxcoefsmat
   
   ' Populate a matrix with the coefficients
   for !i = 1 to !num_rows
      for !j = 1 to !num_cols
         _xxcoefsmat(!i, !j) = _xxcoefs(!j)
      next
   next
   
   ' Multiply the coefficients with the independent variables
   matrix _xxeffs = @emult(_xxcoefsmat, _xxindep_vars)
   
   vector(!num_rows) _xxprobabilities
   
   ' Calculate the probabilities for each observation
   for !i = 1 to !num_rows
      for !j = 1 to !num_cols
         _xxprobabilities(!i) = _xxprobabilities(!i) + _xxeffs(!i, !j)
      next
     
      _xxprobabilities(!i) = @dnorm(_xxprobabilities(!i))
   next
   
   ' Get the average probability
   scalar mean_prob = @mean(_xxprobabilities)
   
   ' Calculate the average effect
   vector(!num_cols) {%me}
   for !i = 1 to !num_cols
      {%me}(!i) = mean_prob * _xxcoefs(!i)
   next
   
endif

' Calculate effect at the mean
if (@isna(%eatm) = 0) then
   ' Get mean of each independent variable
   vector _xxindep_means = @cmean(_xxindep_vars)
   !meanprob = 0
   
   ' Calculate the fitted value for the average observation
   for !i = 1 to !num_cols
      !meanprob = !meanprob + _xxindep_means(!i) * _xxcoefs(!i)
   next
   
   ' Get the value of the pdf for the average observation
   !meanprob = @dnorm(!meanprob)
   
   ' Calculate the effects at the mean
   vector(!num_cols) {%eatm}
   for !i = 1 to !num_cols
            {%eatm}(!i) = !meanprob * _xxcoefs(!i)
      next
endif

' Clean up
smpl @all
delete _xx*



Return to “Estimation”

Who is online

Users browsing this forum: No registered users and 8 guests