passing value to another RM file

jujujuju Member Posts: 39 Guru
edited November 2018 in Help

Hi I use `execute process` to call another RM file.


What's the easiest way to pass a value (number or string) into that function?

 

I thought of a few ways

1. Wire it as input. Wire looks good since it visualizes the flow of data.

But this seems to require making a table of one row by one column and saving it into the repository. In the call RM file I can extract that value into a macro.

 

2. If I store the value in a macro in the main RM file, would it automatically be available in the called RM file?

 

Let me know what you think/how you deal w/ this. Any advice is appreciated. Thanks

 

 

Best Answers

  • IngoRMIngoRM Administrator, Moderator, Employee, RapidMiner Certified Analyst, RapidMiner Certified Expert, Community Manager, RMResearcher, Member, University Professor Posts: 1,751 RM Founder
    Solution Accepted

    Hi,

     

    Although way (1) would be possible, this is too cumbersome in my opinion for short or single values.  Especially if you want to export your processes as web services via RapidMiner Server so that you can invoke them through an URL.  So I only would recommend way (1) if you actually would need to transfer larger inputs.

     

    So I recommend way (2).  I will take the time to explain this in a bit deeper detail here since I don't think some of those hints I will give are documented elsewhere.  Here we go:

     

    1. Use the Context panel

     

    Look into the menu "View" and then "Show Panel" and activate the "Context" panel in case you did not do so already.  I personally prefer to have this together with the Process and the XML tab in the center of my Design view but you can put it wherever you want.  The result should look something like this:

     

    process_macros1.png

     

     

     

     

     

     

     

     

     

     

     

    2. Build a Process using a Macro

     

    Build the process you want to control with the value passed from the outer process (or as web service parameter).  In my example, I simply use a Generate Data operator and use the macro %{number_of_examples} for the parameter defining the size of the example set.  If you do this (at least with the latest versions of RapidMiner), it will complain that the macro is not defined.  This is what we we do in the Context panel now.

     

    In the Context panel, you will find a section in the bottom third called "Macros".  Those are the macros which are set for the whole process but can also be changed from the outside (which we will see in the next step).  Click on the plus icon on the right side which will add a new line.  Use "number_of_examples" as macro name in the left cell and for example "500" as value in the right cell.

     

    The result should look like this:

     

    process_macros2.png

     

     

     

     

     

     

     

     

     

     

    If you execute the process now, it will generate a data set with 5 columns (attributes) and 500 rows (examples).  You can change the value in the process' Context and re-run the proces to see how this changes the result.

     

    Here is the final process.  Make sure to store it in your repository under an arbitrary name.

     

    <?xml version="1.0" encoding="UTF-8"?><process version="7.2.000">
    <context>
    <input/>
    <output/>
    <macros>
    <macro>
    <key>number_of_examples</key>
    <value>500</value>
    </macro>
    </macros>
    </context>
    <operator activated="true" class="process" compatibility="7.2.000" expanded="true" name="Process">
    <process expanded="true">
    <operator activated="true" class="generate_data" compatibility="7.2.000" expanded="true" height="68" name="Generate Data" width="90" x="45" y="34">
    <parameter key="number_examples" value="%{number_of_examples}"/>
    </operator>
    <connect from_op="Generate Data" from_port="output" to_port="result 1"/>
    <portSpacing port="source_input 1" spacing="0"/>
    <portSpacing port="sink_result 1" spacing="0"/>
    <portSpacing port="sink_result 2" spacing="0"/>
    </process>
    </operator>
    </process>

    For more information on macros I would recommend this video here from our friends at RapidMiner Resources: https://www.youtube.com/watch?v=K4aBq-apeqM

     

     

    3. Create the Outer Process

     

    You can now create the process which is invoking the first process above and pass a value to the macro you have defined in the Context.  The easiest way is to just start with a blank process and drag the first process from the repository into the new one.  If you do this, the process will automatically converted into the operator "Execute Process" with the selected process pre-set in the parameters.  Of course you can also add and configure the operator manually.

     

    You can use the Execute Process operator in exactly the same ways as any other operator, i.e. you can pass inputs to it and get results back. Finally, and this is the important piece for this discussion, you can also set the values for macros defined in the process' Context.  Click on the new Execute Process operator and then click on the button "Edit List" for the "macros" parameter of this operator.  In the dialog, you can now add new macros and set, for example, the value for "number_of_examples" to 1,000.  The result should look like this:

     

    process_macros3.png

     

     

     

     

     

     

     

     

     

     

     

     

     

    Close the dialog and run the process.  You will see that you now get 1,000 examples instead of the 500 you have defined in the context.  Again, change the values in this list to see the effect.  And of course you can use now even other macros for the values of this one which can again be defined in the Context so that this can be even handled in a cascading manner.

     

    Here is the XML for the outer process:

     

    <?xml version="1.0" encoding="UTF-8"?><process version="7.2.000">
    <context>
    <input/>
    <output/>
    <macros/>
    </context>
    <operator activated="true" class="process" compatibility="7.2.000" expanded="true" name="Process">
    <process expanded="true">
    <operator activated="true" class="productivity:execute_process" compatibility="7.2.000" expanded="true" height="68" name="Execute Inner Process" width="90" x="112" y="34">
    <parameter key="process_location" value="//Local Repository/processes/Inner Process"/>
    <list key="macros">
    <parameter key="number_of_examples" value="1000"/>
    </list>
    </operator>
    <connect from_op="Execute Inner Process" from_port="result 1" to_port="result 1"/>
    <portSpacing port="source_input 1" spacing="0"/>
    <portSpacing port="sink_result 1" spacing="0"/>
    <portSpacing port="sink_result 2" spacing="0"/>
    </process>
    </operator>
    </process>

    Hope this helps,

    Ingo

  • jujujuju Member Posts: 39 Guru
    Solution Accepted

    wow a class from Ingo - I'm so happy <3<3<3 Thank you very much!

     

    (Let's call the outer process main.rmp, and the process being called f1.rmp)

    I was wondering if it's a must to define the macro in f1.rmp. With a little test I realize:

     

    - the macro must be defined in the CONTEXT panel in f1.rmp. Creating the macro using `set macro` doesn't work.

    - it's possbile to leave the value blank. In this case, f1.rmp doesn't work on it own, and works only when main.rmp calls it and passes it a value 

     

     

    Untitled.png

     

     Code:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <process version="6.4.000">
    <context>
    <input/>
    <output/>
    <macros>
    <macro>
    <key>number_of_examples</key>
    <value/>
    </macro>
    </macros>
    </context>
    <operator activated="true" class="process" compatibility="6.4.000" expanded="true" name="Process">
    <process expanded="true">
    <operator activated="true" class="generate_data" compatibility="6.4.000" expanded="true" height="60" name="Generate Data" width="90" x="380" y="30">
    <parameter key="number_examples" value="%{number_of_examples}"/>
    </operator>
    <connect from_op="Generate Data" from_port="output" to_port="result 1"/>
    <portSpacing port="source_input 1" spacing="0"/>
    <portSpacing port="sink_result 1" spacing="0"/>
    <portSpacing port="sink_result 2" spacing="0"/>
    </process>
    </operator>
    </process>

     

    Thank you again~

Answers

  • IngoRMIngoRM Administrator, Moderator, Employee, RapidMiner Certified Analyst, RapidMiner Certified Expert, Community Manager, RMResearcher, Member, University Professor Posts: 1,751 RM Founder

    You are welcome :smileyvery-happy:

     

    I think we will turn this content into some knowledge base or doc article soon anyway so I thought "eh, whatever, just write it all down" :smileywink:

     

    Your two additions are actually very important - thanks for pointing this out!

     

    Cheers,

    Ingo

Sign In or Register to comment.