Announcement

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

  • Nested Loop

    Hello,
    I would like to replace 0s with 1s where the variable name exists as a value within the variable named "cropcultlast12mos" and foreach hhid. For example, if maize is a value in the cropcultlast12mos and there is a variable names "maize", it should be 1.
    I tried the code below, but it replaces everything with one:
    Code:
    local varrs "amaranth avocados bananas barley bean bushbeans climbingbeans cabbage carrots cassava chickpeas cocoa coffee"
    
    local crops "amaranth avocados bananas barley bean bushbeans climbingbeans cabbage carrots cassava chickpeas cocoa coffeet"
    
    foreach x of local varrs{
        foreach y of local crops{
            bys hhid: replace `x' = "1" if strpos(cropcultlast12mos, "`y'")    
        }
    }

    Kindly help
    Code:
    * Example generated by -dataex-. For more info, type help dataex
    clear
    input str12 hhid str139 cropcultlast12mos str1(amaranth avocados bananas barley bean bushbeans climbingbeans cabbage carrots cassava chickpeas cocoa coffee)
    "CHHHKE000131" "maize bean"                            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000131" "maize bean"                            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000131" "maize bean"                            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000131" "maize bean"                            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000131" "maize bean"                            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000131" "maize bean"                            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000131" "maize bean"                            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000131" "maize bean"                            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "potato maize cabbage avocado other1"   "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "potato maize cabbage avocado other1"   "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "potato maize cabbage avocado other1"   "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "potato maize cabbage avocado other1"   "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "potato maize cabbage avocado other1"   "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "potato maize cabbage avocado other1"   "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "potato maize cabbage avocado other1"   "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "potato maize cabbage avocado other1"   "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "potato maize cabbage avocado other1"   "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "potato maize cabbage avocado other1"   "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "potato maize cabbage avocado other1"   "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "potato maize cabbage avocado other1"   "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000365" "groundnuts bean peas maize"            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000365" "groundnuts bean peas maize"            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000365" "groundnuts bean peas maize"            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000365" "groundnuts bean peas maize"            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000365" "groundnuts bean peas maize"            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000365" "groundnuts bean peas maize"            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000236" "potatoIrish forage maize"              "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000236" "potatoIrish forage maize"              "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000236" "potatoIrish forage maize"              "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000236" "potatoIrish forage maize"              "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000236" "potatoIrish forage maize"              "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000236" "potatoIrish forage maize"              "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000236" "potatoIrish forage maize"              "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000236" "potatoIrish forage maize"              "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000236" "potatoIrish forage maize"              "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000236" "potatoIrish forage maize"              "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000236" "potatoIrish forage maize"              "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000236" "potatoIrish forage maize"              "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000366" "maize pigeonpea"                       "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000366" "maize pigeonpea"                       "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000366" "maize pigeonpea"                       "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000366" "maize pigeonpea"                       "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000366" "maize pigeonpea"                       "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000366" "maize pigeonpea"                       "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000366" "maize pigeonpea"                       "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000366" "maize pigeonpea"                       "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000366" "maize pigeonpea"                       "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000366" "maize pigeonpea"                       "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000469" "bananas other1"                        "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000237" "carrots maize potatoIrish other1 peas" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000237" "carrots maize potatoIrish other1 peas" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000237" "carrots maize potatoIrish other1 peas" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000237" "carrots maize potatoIrish other1 peas" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000237" "carrots maize potatoIrish other1 peas" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000237" "carrots maize potatoIrish other1 peas" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000237" "carrots maize potatoIrish other1 peas" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000237" "carrots maize potatoIrish other1 peas" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000237" "carrots maize potatoIrish other1 peas" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CHHHKE000001" "avocado maize potato bean other1"      "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CCHHKE000164" "bean maize"                            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CCHHKE000164" "bean maize"                            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    "CCHHKE000164" "bean maize"                            "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0" "0"
    end

  • #2
    I guess that the difficulty is that problem needs one loop, not nested loops. Your code replaces every variable with 1 if any of the named variables is matched by a crop name.

    This appears to have the right flavour.

    Code:
    local crops "amaranth avocados bananas barley bean bushbeans climbingbeans cabbage carrots cassava chickpeas cocoa coffee"
    
    foreach y of local crops {
        replace `y' = "1" if strpos(cropcultlast12mos, "`y'")    
    }

    Details, some important:

    Your code doesn't run for me without fixing coffeet which is not a variable in the data example.

    The by: prefix is irrelevant to a calculation like yours within observations. It does no harm, but it's like saying "in each room of my house: add 2 + 2" when the calculation is the same regardless of room in your house.

    A numeric 0, 1 indicator variable is immensely more useful than a string variable with their equivalent values.

    People quite often write nested loops when parallel loops are needed. More guidance at Speaking Stata: Loops in parallel

    Comment


    • #3
      I don't think you need a nested loop at all, I think a single loop might suffice. But I am unclear about a few things:
      • I don't think the bys hhid part is achieving anything in your code. What exactly is its intent? Relatedly, in your data example there seems to be a single string for cropcultlast12mos for each hhid, even though there are multiple observations for each hhid. Is this always the case? Or do you have situations where you may have different values of cropcultlast12mos in different observations of the same hhid? The solution will depend on this.
      • What would you like to do about situations in which one crop name is a subset of another? For instance, with your code, checking for "bean" will throw up 1s for "bushbeans" and "climbingbeans". Is this how you want it?
      • Your varrs and crops macros seem to be identical, except for the last word -- coffee vs coffeet. Is this a typo?
      • I am also unsure why you are using string variables for the individual crops. Would it not be better to use numeric variables, if they are just going to take on the values 0 and 1?
      Last edited by Hemanshu Kumar; 20 Mar 2025, 07:54. Reason: Cross-posted with #2, which flags many of the same issues. You may still want to address my first and second point, though.

      Comment


      • #4
        Hemanshu Kumar raised a key point

        • What would you like to do about situations in which one crop name is a subset of another? For instance, with your code, checking for "bean" will throw up 1s for "bushbeans" and "climbingbeans". Is this how you want it?
        For discussion and technique read

        SJ-22-4 . . . . . . . . . . Stata tip 148: Searching for words within strings
        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N. J. Cox
        Q4/22 SJ 22(4):998--1003 (no commands)
        tip on searching for words within strings


        Comment


        • #5
          Thank you Nick Cox and Hemanshu Kumar . Sorry, I had put the names of crops in the column to be similar to the values of crops in cropcultlast12mos
          I would like a table like this:
          cropcultlast12mos carrots maize potatoirish peas
          carrots maize potatoIrish peas 1 1 1 1
          maize bean 0 1 0 0
          maize pigeonpea 0 1 0 0
          bananas other1 0 0 0 0
          Last edited by Co Ar; 21 Mar 2025, 00:17.

          Comment


          • #6
            What you want is what your code should allow, subject particularly to searching for words.

            Comment


            • #7
              Hello Nick Cox, thanks but seems like I still lack a way of implementing it

              Comment


              • #8
                I don't understand quite what you don't understand. From the answers so far and the paper referenced in #4 you have, so far as I can see, all that you need to know.

                In most respects the problem is simpler than your original code in #1 implies.

                1. The problem calls for a single loop, not nested loops. For more on that if you wish, see https://journals.sagepub.com/doi/pdf...6867X211063415

                2. The identifier is irrelevant to looking at the crop mix.

                3. You are going to be better off producing numeric indicator variables with values 0 and 1 than string variables with values "0" and "1". For more on the value of such variables if you wish, see https://journals.sagepub.com/doi/pdf...36867X19830921

                In one respect, as well spotted by Hemanshu Kumar, the problem is more complicated. You'll find bean inside bushbeans and so forth and so you must search for words not strings. Now looking for " beans " not "beans" is a step forward but at the beginning of a string you could have "beans " and there could be a similar problem at the end of a string. So, one method is

                * get Stata to tell you the length of the string and the length of the string if a particular word were to be deleted

                * if the lengths are different, the word was present as a word.

                Note that you don't need to, and should not, delete the word. You just need Stata to do the calculation.

                This example is based on yours, with extra observations to check that the code does the right thing with beans, or indeed anything equally problematic.

                Code:
                * Example generated by -dataex-. For more info, type help dataex
                clear
                input str37 cropcultlast12mos
                "maize bean"                          
                "potato maize cabbage avocado other1"  
                "groundnuts bean peas maize"          
                "potatoIrish forage maize"            
                "maize pigeonpea"                      
                "bananas other1"                      
                "carrots maize potatoIrish other1 peas"
                "avocado maize potato bean other1"    
                "bushbeans maize"  
                "bean bushbeans"                        
                end
                
                foreach crop in amaranth avocados bananas barley bean bushbeans {
                    gen `crop' = strlen(cropcultlast12mos) - strlen(subinword(cropcultlast12mos, "`crop'", "", .)) > 0
                }
                
                list
                     +--------------------------------------------------------------------------------------------------+
                     |                     cropcultlast12mos   amaranth   avocados   bananas   barley   bean   bushbe~s |
                     |--------------------------------------------------------------------------------------------------|
                  1. |                            maize bean          0          0         0        0      1          0 |
                  2. |   potato maize cabbage avocado other1          0          0         0        0      0          0 |
                  3. |            groundnuts bean peas maize          0          0         0        0      1          0 |
                  4. |              potatoIrish forage maize          0          0         0        0      0          0 |
                  5. |                       maize pigeonpea          0          0         0        0      0          0 |
                     |--------------------------------------------------------------------------------------------------|
                  6. |                        bananas other1          0          0         1        0      0          0 |
                  7. | carrots maize potatoIrish other1 peas          0          0         0        0      0          0 |
                  8. |      avocado maize potato bean other1          0          0         0        0      1          0 |
                  9. |                       bushbeans maize          0          0         0        0      0          1 |
                 10. |                        bean bushbeans          0          0         0        0      1          1 |
                     +--------------------------------------------------------------------------------------------------+
                Last edited by Nick Cox; 21 Mar 2025, 04:14.

                Comment


                • #9
                  You could also achieve the same result using regular expressions:

                  Code:
                  foreach crop in amaranth avocados bananas barley bean bushbeans {
                      gen `crop' = regexm(cropcultlast12mos, "\b`crop'\b")
                  }
                  You did not answer a question I had posed earlier:
                  in your data example there seems to be a single string for cropcultlast12mos for each hhid, even though there are multiple observations for each hhid. Is this always the case? Or do you have situations where you may have different values of cropcultlast12mos in different observations of the same hhid?
                  If you always have the same cropcultlast12mos string for an hhid, then either Nick or my solutions should suffice. If not, then you will want to create the final variable by taking the max over all the observations for an hhid. You can use something like
                  Code:
                  egen `crop'_final = max(`crop'), by(hhid)
                  inside the loop to do that.
                  Last edited by Hemanshu Kumar; 21 Mar 2025, 03:58.

                  Comment

                  Working...
                  X