Announcement

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

  • Find a value that equates two averages using Mata

    Hello everyone,
    I trying find the value, x, the equates the average of variable2 to variable1. Below is my attempt using Mata but I keep on getting errors. Please can someone help correct the errors in the code below.
    Thank you.

    Patrick
    Errors:


    variable1 = min(1, max(0, (0.95 :- SWCIndex) :* conv_factor))
    ' ' found where almost anything else expected
    r(3000);

    : variable2 = min(1, max(0, 1 :- x :- YieldIndex))
    ' variable2' found where almost anything else expected
    r(3000);



    Code:
    mata
    void myfunc(todo, x, lnf, g, H)
    {
    
    
    SWCIndex=st_data(., "SWCIndex")
    conv_factor=st_data(.,"conv_factor")
    YieldIndex=st_data(.,"YieldIndex")
    
    variable1 = min(1, max(0, (0.95 :- SWCIndex) :* conv_factor))
    variable2 = min(1, max(0, 1 :- x :- YieldIndex))
    
    mean_v1=mean(variable1)
    mean_v2=mean(variable2)
    
    diff_sq=(mean_v1-mean_v2)^2
    
    lnf=-diff_sq
    
    
    
    }
    
    S = optimize_init()
    optimize_init_which(S, "max")
    optimize_init_evaluator(S, &myfunc())
    optimize_init_params(S, 0)
    bh = optimize(S)
    
    bh
    end
    
    clear
    input double YieldIndex float SWCIndex double conv_factor
    1.0861081686220508 .8990123 .6226526011135668
    .6649476376589332 .8974741 .6226526011135668
    .5527689833452102 .9240186 .6226526011135668
    .9253806198611291 .9500761 .6226526011135668
    .9087439508922139 1.1295747 .6226526011135668
    1.2941161617887758 1.0016987 .6226526011135668
    .3341956330126147 .6080579 .6226526011135668
    .853106566143711 1.3886855 .6226526011135668
    1.4052729869411842 1.1745064 .6226526011135668
    1.135791047177306 1.0770227 .6226526011135668
    .9909411357309351 .8795984 .6226526011135668
    .7024821439818003 .9564832 .6226526011135668
    .7824689060953668 1.0973326 .6226526011135668
    1.316751439047902 1.1611431 .6226526011135668
    1.6404846532462987 1.2310717 .6226526011135668
    .909491036549925 .9555679 .6226526011135668
    1.2837267687754703 1.0622913 .6226526011135668
    1.2891894358766425 1.0278761 .6226526011135668
    1.3410032409929848 1.3822783 .6226526011135668
    .4042373654867438 1.0403242 .6226526011135668
    end
    Last edited by Patrick Frimpong Manso; 07 May 2025, 13:41.

  • #2
    Part of the problem (although perhaps not the entirety of the problem) is that the max(.) and min(.) functions require one argument and you are, in effect, providing two arguments. For example, instead of
    Code:
    variable1 = min(1, max(0, (0.95 :- SWCIndex) :* conv_factor))
    you should use
    Code:
    variable1 = min((1, max((0, (0.95 :- SWCIndex) :* conv_factor))))
    This way the max(.) and min(.) functions are each receiving a single argument (in this case 1x2 vectors) rather than two arguments as is suggested when the extra parentheses I introduced are omitted.

    Comment


    • #3
      Thank you John for your response. However, I still get an error.

      Code:
         myfunc():  3200  conformability error
            opt__calluser0_d():     -  function returned error
            opt__d0_calluser():     -  function returned error
          deriv__call1user_d():     -  function returned error
       _deriv__compute_value():     -  function returned error
                      _deriv():     -  function returned error
             opt__eval_nr_d0():     -  function returned error
                   opt__eval():     -  function returned error
      opt__looputil_iter0_common():     -  function returned error
      opt__looputil_iter0_nr():     -  function returned error
                opt__loop_nr():     -  function returned error
                   opt__loop():     -  function returned error
                    optimize():     -  function returned error
                       <istmt>:     -  function returned error
      r(3200);

      Comment


      • #4
        Lets take a step back. The complication is only due to your requirement that variables variable1 and variable2 remain between 0 and 1. That is what the min() and max() are doing in the creation of your variables. If we remove those, than x is just the mean of variable2 minus mean of variable1. So you have an easy solution if don't enforce the bounds. More importantly, enforcing such bounds is in my experience almost always wrong:
        1. either the bounds are mistaken. For example, some people want to enforce that income is always positive, but especially among the self-employed income can be negative, or
        2. violating the bounds is an indication of a data-error. In which case enforcing bounds like this is probably the worst thing you can do.
        So automatically enforcing bounds like that is almost always a bad idea, and in this case it also makes your problem unnecessarily hard. So my suggestion would be to first ignore the bounds and figure out how many observations violate your bounds, how big those violations are, and try to figure out why they occur. For example, is this rounding error (remember that you are not the only one rounding, the computer rounds when doing computations, and most respondents also round when they answer questions), or is the respondent answering in percentages when you asked for proportions, or ... If you know why they occur you can fix them or declare them missing. The end result will be better data, and an easier way to get it. Sounds like a win-win to me.
        ---------------------------------
        Maarten L. Buis
        University of Konstanz
        Department of history and sociology
        box 40
        78457 Konstanz
        Germany
        http://www.maartenbuis.nl
        ---------------------------------

        Comment


        • #5
          Thank you Maarten. I really appreciate your suggestions.

          Comment

          Working...
          X