Thursday, July 12, 2012

Remove a subset from a global - Stata


* This program will remove from a global a set of specified values
* I believe this is the same in sigma algebra of subtracting a set from another
* I figure there is probably a prewritten command for this but I have not been able to find it.

cap program drop takefromglobal
program define takefromglobal
 
  * First define a local called temp to hold the initial values of the global
  local temp ${`1'}
 
  * Empty the global
  global `1'
 
  * Loop through each of the old values
  foreach v of local temp {
   
* Start counting at 0
    local i = 0

* Create a local that indicates that this value should be skipped (initially assume no skipping)
local skip = 0

* Loop through all of the user specified inputs `0'
    foreach vv in `0' {

* We will skip the first one since we know it is just the global specified
      local i = `i' + 1

 * If we are past the first input in the local and one our values to exclude matches the value in the global skip that value
 if `i' > 1 & "`vv'"=="`v'" local skip = 1
    }

* If the current value is not to be skipped then add it to the new global list
if `skip' == 0 global `1' ${`1'} `v'
  }
end

global XYZ a b c d e f g a b c d e

di "$XYZ"

takefromglobal XYZ a b c

di "$XYZ"

5 comments:

  1. Big fan of the blog, but this one is a bit abstract to me (and I have no doubt it would be very helpful in my line of work).

    Can you give a bit more of a concrete example for this one?

    I really do love this blog and have been recommending it a TON to others.

    ReplyDelete
    Replies
    1. ***** Reply

      * Imagine you have a large list of variables.
      * Say 1000 of them and they are assumbled dynamically into a global list

      global big_list
      forv i = 1/1000 {
      global big_list $big_list var_item_`i'
      }

      di "$big_list"

      * And you want to use the global in commands but a few of the items need to be removed.
      * Say items var_item_944 var_item_654 var_item_100 var_item_999

      * Instead of modifying how the global was created you just want to remove a few items from it

      takefromglobal big_list var_item_944 var_item_654 var_item_100 var_item_999

      Delete
    2. Oh, and thanks for the encouragement!

      Delete
  2. You could also use the macro function -subinstr-

    local xyz a b c d e f g a b c d e
    local a a b c
    local b: subinstr local xyz "`a'" "", all word
    local c : list retokenize b // not necessary but removes excess spaces
    disp "`c'"

    ReplyDelete
    Replies
    1. Good comment Scott. This built in code is better than a user written script. I should look more into macro functions. Do you know of any guides?

      Delete