Announcement

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

  • Splitting string

    Dear All,

    I have the following dataset:

    Code:
    * Example generated by -dataex-. For more info, type help    dataex
    clear
    input str17 country str3 iso str5 region float score byte    rank str10    interval    float    year    str3    min    str4    max
    "Argentina"  "ARG" "AME"   3.5 57 "2.9 - 4.4"  2001 "2.9"    " 4.4"
    "Australia"  "AUS" "AP"    8.5 11 "6.8 - 9.4"  2001 "6.8"    " 9.4"
    "Austria"    "AUT" "WE/EU" 7.8 15 "7.2 - 8.7"  2001 "7.2"    " 8.7"
    "Azerbaijan" "AZE" "ECA"     2 84 "1.8 - 2.2"  2001 "1.8"    " 2.2"
    "Bangladesh" "BGD" "AP"     .4 91 "-1.7 - 3.8" 2001 "-1."    "- 3."
    "Belgium"    "BEL" "WE/EU" 6.6 24 "5.7 - 7.6"  2001 "5.7"    " 7.6"
    "Bolivia"    "BOL" "AME"     2 84 "1.5 - 3.0"  2001 "1.5"    " 3.0"
    "Botswana"   "BWA" "SSA"     6 26 "5.6 - 6.6"  2001 "5.6"    " 6.6"
    end
    I generated min and max using:

    Code:
    gen min=substr(interval, 1,3)
    gen max=substr(interval, 6,4)
    However, when the first number is negative (fifth row, for instance), I cannot obtain the full number (I will convert later the string to number) because of the -. Is there any way I can solve this problem and having -1.7 rather than -1. I am appending together multiple files and it is tedious to do this manually. By the way, I cannot even understand why I should write

    Code:
    gen max=substr(interval, 6,4)
    rather than

    Code:
    gen max=substr(interval, 6,3)
    In the latter case I got just the integer and the decimal separator.

    Thanks in advance for your help.

    Dario

  • #2
    You can specify a condition that applies if the interval starts with a negative sign:

    Code:
    gen min= cond(substr(interval, 1, 1)=="-", substr(interval, 1, 4), substr(interval, 1, 3))
    Otherwise, regular expressions are suited for these kinds of problems:

    Code:
    gen min= ustrregexra(interval, "(.*)-(.*)", "$1")
    gen max= ustrregexra(interval, "(.*)-(.*)", "$2")

    Comment


    • #3
      Alternatively:
      Code:
      drop min max
      split interval, gen(m) parse(" - ") destring
      rename (m1 m2) (min max)

      Comment


      • #4
        Andrew Musau and Dirk Enzmann Thanks a lot for your help!

        Comment


        • #5
          Originally posted by Dario Maimone Ansaldo Patti View Post
          By the way, I cannot even understand why I should write

          Code:
          gen max=substr(interval, 6,4)
          rather than

          Code:
          gen max=substr(interval, 6,3)
          In the latter case I got just the integer and the decimal separator.

          Thanks in advance for your help.

          Dario
          All characters are counted by -substr()-, and the decimal point is a character. A space within the strings would also count as a character. Therefore, sometimes you need to apply -strtrim()- and -stritrim()- functions to eliminate unwanted spaces.

          Code:
          help strtrim()

          Comment


          • #6
            Watch out also for numbers of 10.0 or more and for negative signs on the upper limit.

            This works also for your data example,

            Code:
            split interval, parse(" - ") destring

            Comment


            • #7
              Thanks again for your help.

              Comment


              • #8
                Clearly the code of #6 is redundant given #3.

                Comment


                • #9
                  Originally posted by Andrew Musau View Post

                  Otherwise, regular expressions are suited for these kinds of problems:

                  Code:
                  gen min= ustrregexra(interval, "(.*)-(.*)", "$1")
                  gen max= ustrregexra(interval, "(.*)-(.*)", "$2")
                  Dear Andrew,

                  I wasn't aware of this behavior of usstrregxra, but it could make things a lot easier in my work. Thank you!
                  Unfortunately I couldn't find anything about it on the relevant help page. Can you point me to where this use of “$1” and “$2” is described?

                  Thanks again,
                  Benno

                  Comment


                  • #10
                    The documentation is not detailed, so you need to find external sources. The Unicode regular expression parser is the ICU regular expression engine documented at https://unicode-org.github.io/icu/us...gs/regexp.html. For your specific question, see the response in https://stackoverflow.com/questions/...ar-expressions.

                    Comment


                    • #11
                      Thanks for the web links. I already knew what those $1 and $2 meant. Because that's basically the same as using ustrregexs(n). What I didn't know was that usstrregxra could be used this way. The Stata help on this is quite sparse and I wouldn't have been able to figure it out from the ICU documentation either.

                      Comment

                      Working...
                      X