Destring variables with fractions












3















I have string variables in my data that contain fractions and non-integers.



For example:



3 2/3 
8 1/2
1.65
6 1/4
0.235


Stata cannot destring these variables with the destring command.



Is there anything I can do to convert my string variables to numeric so I can use them for analysis?










share|improve this question





























    3















    I have string variables in my data that contain fractions and non-integers.



    For example:



    3 2/3 
    8 1/2
    1.65
    6 1/4
    0.235


    Stata cannot destring these variables with the destring command.



    Is there anything I can do to convert my string variables to numeric so I can use them for analysis?










    share|improve this question



























      3












      3








      3








      I have string variables in my data that contain fractions and non-integers.



      For example:



      3 2/3 
      8 1/2
      1.65
      6 1/4
      0.235


      Stata cannot destring these variables with the destring command.



      Is there anything I can do to convert my string variables to numeric so I can use them for analysis?










      share|improve this question
















      I have string variables in my data that contain fractions and non-integers.



      For example:



      3 2/3 
      8 1/2
      1.65
      6 1/4
      0.235


      Stata cannot destring these variables with the destring command.



      Is there anything I can do to convert my string variables to numeric so I can use them for analysis?







      stata






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 22 '18 at 11:14









      Pearly Spencer

      11.2k173663




      11.2k173663










      asked Nov 22 '18 at 10:56









      Stephan ColbertStephan Colbert

      233




      233
























          2 Answers
          2






          active

          oldest

          votes


















          2














          Below code, while extending to cases like " 3 2/3" or "- 6 1/4" (notice the spaces), might also be useful for saving some typings.



          replace var1 = subinstr(var1, "- ", "-",.)
          split var1, generate(x) destring force

          egen y = ends(var1) if strmatch(var1,"*/*"), last
          split y, destring force p("/")

          replace x1 = cond(x1<0, x1-y1/y2, cond(x1!=.,x1+y1/y2, y1/y2)) if y1!=.
          keep var1 x1





          share|improve this answer































            1














            If all values in your string variables look the same as in your example, you can do the following:



            clear

            input str6 var1
            "3 2/3"
            "8 1/2"
            "6/8"
            "-2/3"
            "1.65"
            "-6 1/4"
            "-0.235"
            end

            replace var1 = subinstr(var1," ",":", .)
            replace var1 = "0:" + var1 if !strmatch(var1, "*:*") & !strmatch(var1, "-*") & strmatch(var1, "*/*")
            replace var1 = "-0:" + substr(var1, 2, .) if !strmatch(var1, "*:*") & strmatch(var1, "-*") & strmatch(var1, "*/*")
            replace var1 = subinstr(var1,":"," ", .)

            generate double var2 = real(var1) if !strmatch(var1, "*/*")

            replace var2 = real(substr(var1, 1, strpos(var1, " ") - 1)) + ///
            ( real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
            real(substr(var1, strpos(var1, "/") + 1, .)) ) ///
            if strmatch(var1, "*/*") & !strmatch(var1, "-*")

            replace var2 = - ( abs(real(substr(var1, 1, strpos(var1, " ") - 1))) + ///
            ( real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
            real(substr(var1, strpos(var1, "/") + 1, .)) ) ) ///
            if strmatch(var1, "*/*") & strmatch(var1, "-*")


            For more information on the use of each function, type help followed by its
            name: real(), strmatch(), substr(), subinstr(), strpos(), abs().





            EDIT:



            The aforementioned approach relies on string manipulation using Stata's string functions and hence is lengthier than the solution provided in the other answer.



            Nevertheless, you can shorten the code a bit and improve readability as follows:



            local m1 !strmatch(var1, "* *")
            local m2 strmatch(var1, "-*") & strmatch(var1, "*/*")

            replace var1 = cond(`m1' & !`m2', "0 " + var1, ///
            cond(`m1' & `m2', "-0 " + substr(var1, 2, .), var1 + "" ) )

            local e1 real(substr(var1, 1, strpos(var1, " ") - 1))
            local e2 (real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
            real(substr(var1, strpos(var1, "/") + 1, .)) )

            generate var2 = cond(!strmatch(var1, "*/*"), real(var1), ///
            cond(!`m2', `e1' + `e2', - ( abs(`e1') + `e2' ) ) )


            In both cases, you will get:



            list, separator(0)

            +---------------------+
            | var1 var2 |
            |---------------------|
            1. | 3 2/3 3.6666667 |
            2. | 8 1/2 8.5 |
            3. | 0 6/8 .75 |
            4. | -0 2/3 -.66666667 |
            5. | 1.65 1.65 |
            6. | -6 1/4 -6.25 |
            7. | -0.235 -.235 |
            +---------------------+





            share|improve this answer

























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53429401%2fdestring-variables-with-fractions%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              2














              Below code, while extending to cases like " 3 2/3" or "- 6 1/4" (notice the spaces), might also be useful for saving some typings.



              replace var1 = subinstr(var1, "- ", "-",.)
              split var1, generate(x) destring force

              egen y = ends(var1) if strmatch(var1,"*/*"), last
              split y, destring force p("/")

              replace x1 = cond(x1<0, x1-y1/y2, cond(x1!=.,x1+y1/y2, y1/y2)) if y1!=.
              keep var1 x1





              share|improve this answer




























                2














                Below code, while extending to cases like " 3 2/3" or "- 6 1/4" (notice the spaces), might also be useful for saving some typings.



                replace var1 = subinstr(var1, "- ", "-",.)
                split var1, generate(x) destring force

                egen y = ends(var1) if strmatch(var1,"*/*"), last
                split y, destring force p("/")

                replace x1 = cond(x1<0, x1-y1/y2, cond(x1!=.,x1+y1/y2, y1/y2)) if y1!=.
                keep var1 x1





                share|improve this answer


























                  2












                  2








                  2







                  Below code, while extending to cases like " 3 2/3" or "- 6 1/4" (notice the spaces), might also be useful for saving some typings.



                  replace var1 = subinstr(var1, "- ", "-",.)
                  split var1, generate(x) destring force

                  egen y = ends(var1) if strmatch(var1,"*/*"), last
                  split y, destring force p("/")

                  replace x1 = cond(x1<0, x1-y1/y2, cond(x1!=.,x1+y1/y2, y1/y2)) if y1!=.
                  keep var1 x1





                  share|improve this answer













                  Below code, while extending to cases like " 3 2/3" or "- 6 1/4" (notice the spaces), might also be useful for saving some typings.



                  replace var1 = subinstr(var1, "- ", "-",.)
                  split var1, generate(x) destring force

                  egen y = ends(var1) if strmatch(var1,"*/*"), last
                  split y, destring force p("/")

                  replace x1 = cond(x1<0, x1-y1/y2, cond(x1!=.,x1+y1/y2, y1/y2)) if y1!=.
                  keep var1 x1






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 24 '18 at 1:57









                  Romalpa AkzoRomalpa Akzo

                  14116




                  14116

























                      1














                      If all values in your string variables look the same as in your example, you can do the following:



                      clear

                      input str6 var1
                      "3 2/3"
                      "8 1/2"
                      "6/8"
                      "-2/3"
                      "1.65"
                      "-6 1/4"
                      "-0.235"
                      end

                      replace var1 = subinstr(var1," ",":", .)
                      replace var1 = "0:" + var1 if !strmatch(var1, "*:*") & !strmatch(var1, "-*") & strmatch(var1, "*/*")
                      replace var1 = "-0:" + substr(var1, 2, .) if !strmatch(var1, "*:*") & strmatch(var1, "-*") & strmatch(var1, "*/*")
                      replace var1 = subinstr(var1,":"," ", .)

                      generate double var2 = real(var1) if !strmatch(var1, "*/*")

                      replace var2 = real(substr(var1, 1, strpos(var1, " ") - 1)) + ///
                      ( real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
                      real(substr(var1, strpos(var1, "/") + 1, .)) ) ///
                      if strmatch(var1, "*/*") & !strmatch(var1, "-*")

                      replace var2 = - ( abs(real(substr(var1, 1, strpos(var1, " ") - 1))) + ///
                      ( real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
                      real(substr(var1, strpos(var1, "/") + 1, .)) ) ) ///
                      if strmatch(var1, "*/*") & strmatch(var1, "-*")


                      For more information on the use of each function, type help followed by its
                      name: real(), strmatch(), substr(), subinstr(), strpos(), abs().





                      EDIT:



                      The aforementioned approach relies on string manipulation using Stata's string functions and hence is lengthier than the solution provided in the other answer.



                      Nevertheless, you can shorten the code a bit and improve readability as follows:



                      local m1 !strmatch(var1, "* *")
                      local m2 strmatch(var1, "-*") & strmatch(var1, "*/*")

                      replace var1 = cond(`m1' & !`m2', "0 " + var1, ///
                      cond(`m1' & `m2', "-0 " + substr(var1, 2, .), var1 + "" ) )

                      local e1 real(substr(var1, 1, strpos(var1, " ") - 1))
                      local e2 (real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
                      real(substr(var1, strpos(var1, "/") + 1, .)) )

                      generate var2 = cond(!strmatch(var1, "*/*"), real(var1), ///
                      cond(!`m2', `e1' + `e2', - ( abs(`e1') + `e2' ) ) )


                      In both cases, you will get:



                      list, separator(0)

                      +---------------------+
                      | var1 var2 |
                      |---------------------|
                      1. | 3 2/3 3.6666667 |
                      2. | 8 1/2 8.5 |
                      3. | 0 6/8 .75 |
                      4. | -0 2/3 -.66666667 |
                      5. | 1.65 1.65 |
                      6. | -6 1/4 -6.25 |
                      7. | -0.235 -.235 |
                      +---------------------+





                      share|improve this answer






























                        1














                        If all values in your string variables look the same as in your example, you can do the following:



                        clear

                        input str6 var1
                        "3 2/3"
                        "8 1/2"
                        "6/8"
                        "-2/3"
                        "1.65"
                        "-6 1/4"
                        "-0.235"
                        end

                        replace var1 = subinstr(var1," ",":", .)
                        replace var1 = "0:" + var1 if !strmatch(var1, "*:*") & !strmatch(var1, "-*") & strmatch(var1, "*/*")
                        replace var1 = "-0:" + substr(var1, 2, .) if !strmatch(var1, "*:*") & strmatch(var1, "-*") & strmatch(var1, "*/*")
                        replace var1 = subinstr(var1,":"," ", .)

                        generate double var2 = real(var1) if !strmatch(var1, "*/*")

                        replace var2 = real(substr(var1, 1, strpos(var1, " ") - 1)) + ///
                        ( real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
                        real(substr(var1, strpos(var1, "/") + 1, .)) ) ///
                        if strmatch(var1, "*/*") & !strmatch(var1, "-*")

                        replace var2 = - ( abs(real(substr(var1, 1, strpos(var1, " ") - 1))) + ///
                        ( real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
                        real(substr(var1, strpos(var1, "/") + 1, .)) ) ) ///
                        if strmatch(var1, "*/*") & strmatch(var1, "-*")


                        For more information on the use of each function, type help followed by its
                        name: real(), strmatch(), substr(), subinstr(), strpos(), abs().





                        EDIT:



                        The aforementioned approach relies on string manipulation using Stata's string functions and hence is lengthier than the solution provided in the other answer.



                        Nevertheless, you can shorten the code a bit and improve readability as follows:



                        local m1 !strmatch(var1, "* *")
                        local m2 strmatch(var1, "-*") & strmatch(var1, "*/*")

                        replace var1 = cond(`m1' & !`m2', "0 " + var1, ///
                        cond(`m1' & `m2', "-0 " + substr(var1, 2, .), var1 + "" ) )

                        local e1 real(substr(var1, 1, strpos(var1, " ") - 1))
                        local e2 (real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
                        real(substr(var1, strpos(var1, "/") + 1, .)) )

                        generate var2 = cond(!strmatch(var1, "*/*"), real(var1), ///
                        cond(!`m2', `e1' + `e2', - ( abs(`e1') + `e2' ) ) )


                        In both cases, you will get:



                        list, separator(0)

                        +---------------------+
                        | var1 var2 |
                        |---------------------|
                        1. | 3 2/3 3.6666667 |
                        2. | 8 1/2 8.5 |
                        3. | 0 6/8 .75 |
                        4. | -0 2/3 -.66666667 |
                        5. | 1.65 1.65 |
                        6. | -6 1/4 -6.25 |
                        7. | -0.235 -.235 |
                        +---------------------+





                        share|improve this answer




























                          1












                          1








                          1







                          If all values in your string variables look the same as in your example, you can do the following:



                          clear

                          input str6 var1
                          "3 2/3"
                          "8 1/2"
                          "6/8"
                          "-2/3"
                          "1.65"
                          "-6 1/4"
                          "-0.235"
                          end

                          replace var1 = subinstr(var1," ",":", .)
                          replace var1 = "0:" + var1 if !strmatch(var1, "*:*") & !strmatch(var1, "-*") & strmatch(var1, "*/*")
                          replace var1 = "-0:" + substr(var1, 2, .) if !strmatch(var1, "*:*") & strmatch(var1, "-*") & strmatch(var1, "*/*")
                          replace var1 = subinstr(var1,":"," ", .)

                          generate double var2 = real(var1) if !strmatch(var1, "*/*")

                          replace var2 = real(substr(var1, 1, strpos(var1, " ") - 1)) + ///
                          ( real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
                          real(substr(var1, strpos(var1, "/") + 1, .)) ) ///
                          if strmatch(var1, "*/*") & !strmatch(var1, "-*")

                          replace var2 = - ( abs(real(substr(var1, 1, strpos(var1, " ") - 1))) + ///
                          ( real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
                          real(substr(var1, strpos(var1, "/") + 1, .)) ) ) ///
                          if strmatch(var1, "*/*") & strmatch(var1, "-*")


                          For more information on the use of each function, type help followed by its
                          name: real(), strmatch(), substr(), subinstr(), strpos(), abs().





                          EDIT:



                          The aforementioned approach relies on string manipulation using Stata's string functions and hence is lengthier than the solution provided in the other answer.



                          Nevertheless, you can shorten the code a bit and improve readability as follows:



                          local m1 !strmatch(var1, "* *")
                          local m2 strmatch(var1, "-*") & strmatch(var1, "*/*")

                          replace var1 = cond(`m1' & !`m2', "0 " + var1, ///
                          cond(`m1' & `m2', "-0 " + substr(var1, 2, .), var1 + "" ) )

                          local e1 real(substr(var1, 1, strpos(var1, " ") - 1))
                          local e2 (real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
                          real(substr(var1, strpos(var1, "/") + 1, .)) )

                          generate var2 = cond(!strmatch(var1, "*/*"), real(var1), ///
                          cond(!`m2', `e1' + `e2', - ( abs(`e1') + `e2' ) ) )


                          In both cases, you will get:



                          list, separator(0)

                          +---------------------+
                          | var1 var2 |
                          |---------------------|
                          1. | 3 2/3 3.6666667 |
                          2. | 8 1/2 8.5 |
                          3. | 0 6/8 .75 |
                          4. | -0 2/3 -.66666667 |
                          5. | 1.65 1.65 |
                          6. | -6 1/4 -6.25 |
                          7. | -0.235 -.235 |
                          +---------------------+





                          share|improve this answer















                          If all values in your string variables look the same as in your example, you can do the following:



                          clear

                          input str6 var1
                          "3 2/3"
                          "8 1/2"
                          "6/8"
                          "-2/3"
                          "1.65"
                          "-6 1/4"
                          "-0.235"
                          end

                          replace var1 = subinstr(var1," ",":", .)
                          replace var1 = "0:" + var1 if !strmatch(var1, "*:*") & !strmatch(var1, "-*") & strmatch(var1, "*/*")
                          replace var1 = "-0:" + substr(var1, 2, .) if !strmatch(var1, "*:*") & strmatch(var1, "-*") & strmatch(var1, "*/*")
                          replace var1 = subinstr(var1,":"," ", .)

                          generate double var2 = real(var1) if !strmatch(var1, "*/*")

                          replace var2 = real(substr(var1, 1, strpos(var1, " ") - 1)) + ///
                          ( real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
                          real(substr(var1, strpos(var1, "/") + 1, .)) ) ///
                          if strmatch(var1, "*/*") & !strmatch(var1, "-*")

                          replace var2 = - ( abs(real(substr(var1, 1, strpos(var1, " ") - 1))) + ///
                          ( real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
                          real(substr(var1, strpos(var1, "/") + 1, .)) ) ) ///
                          if strmatch(var1, "*/*") & strmatch(var1, "-*")


                          For more information on the use of each function, type help followed by its
                          name: real(), strmatch(), substr(), subinstr(), strpos(), abs().





                          EDIT:



                          The aforementioned approach relies on string manipulation using Stata's string functions and hence is lengthier than the solution provided in the other answer.



                          Nevertheless, you can shorten the code a bit and improve readability as follows:



                          local m1 !strmatch(var1, "* *")
                          local m2 strmatch(var1, "-*") & strmatch(var1, "*/*")

                          replace var1 = cond(`m1' & !`m2', "0 " + var1, ///
                          cond(`m1' & `m2', "-0 " + substr(var1, 2, .), var1 + "" ) )

                          local e1 real(substr(var1, 1, strpos(var1, " ") - 1))
                          local e2 (real(substr(var1, strpos(var1, " "), strpos(var1, "/") - strpos(var1, " "))) / ///
                          real(substr(var1, strpos(var1, "/") + 1, .)) )

                          generate var2 = cond(!strmatch(var1, "*/*"), real(var1), ///
                          cond(!`m2', `e1' + `e2', - ( abs(`e1') + `e2' ) ) )


                          In both cases, you will get:



                          list, separator(0)

                          +---------------------+
                          | var1 var2 |
                          |---------------------|
                          1. | 3 2/3 3.6666667 |
                          2. | 8 1/2 8.5 |
                          3. | 0 6/8 .75 |
                          4. | -0 2/3 -.66666667 |
                          5. | 1.65 1.65 |
                          6. | -6 1/4 -6.25 |
                          7. | -0.235 -.235 |
                          +---------------------+






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Nov 26 '18 at 18:48

























                          answered Nov 22 '18 at 11:11









                          Pearly SpencerPearly Spencer

                          11.2k173663




                          11.2k173663






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53429401%2fdestring-variables-with-fractions%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

                              Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

                              A Topological Invariant for $pi_3(U(n))$