Announcement

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

  • Formatting Several Variables using a Loop


    Hello
    I have several variables (68) consisting of strings, integers, and floats. I am trying to format it using a loop and using if-else condition.
    Here's the dataex

    Code:
    clear all
    input str50 var1 int var2 str50 var3 float var4
    Sarita            25    Geeta    23.1
    mushkanchan 31          Subha    18.9
    Kanchandeviparmer    21 Kamla       81.3
    Laxmi  23               Subhaparmar    27.1
    Ram      21             Sarita        23
    Sita      22            Subha     34
    Haru       18           Santosh     22
    "hari kana" 23       "Santosh K Dash" 23.5
    end
    The code I used to do the formatting is

    Code:
    local vars var2 var4
    foreach var of varlist var1-var4{
    
       * Formatting strings
    local j : word [Math Processing Error]vars′of  var'
       if j=[Math Processing Error]var′{    format%30s   }   ⋅Forma∈g∫e≥rsandfloats   elseifj=  vars' {
           format %20g
        }
        }
    That code has an error. I was trying with if-else condition. But could not succeed. Any help will be greatly appreciated.
    Last edited by Santosh Dash; 01 Feb 2020, 22:34.

  • #2
    The Statalist software seems to have had some sort of problem with your code blocks. However, your problem can be solved without loops. If I understand correctly, you want to apply a format of %30s to all string variables, and a format of %20g to all numeric variables.
    Code:
    ds, has(type string)
    format %30s `r(varlist)'
    ds, has(type numeric)
    format %20g `r(varlist)'

    Comment


    • #3
      William Lisowski Thank you for your reply. I tried with that command (#2). But numeric formatting was not successful. I am getting a message:

      Code:
      invalid %format
      I am reproducing the code blocks (#1)
      Code:
      clear all
      input str50 var1 int var2 str50 var3 float var4
      whatisyourname      20  whatisyourname 22.4
      Sarita            25    Geeta    23.1
      mushkanchan 31          Subha    18.9
      Kanchandeviparmer    21 Kamla       81.3
      Laxmi  23               Subhaparmar    27.1
      Ram      21             Sarita        23
      Sita      22            Subha     34
      Haru       18           Santosh     22
      "hari kana" 23       "Santosh K Dash" 23.5
      end
      This is the code I was trying:

      Code:
      local vars var2 var4 
      foreach var of varlist var1-var4{
         
         * Formatting strings
      local j : word `vars' of `var'
         if j=`var' {
             format %50s
          }
          
          * Formatting integers and floats
          else if j = `vars' {
             format %50s
          }
          }

      Comment


      • #4
        The error message tells you that you did not use a valid numeric format when you tried to format your numbers. I copied the %20g format from post #1 without thinking, that is not valid - %20.0g is what is wanted. Certainly not %50s as you show in post #3 - that is for string values, not numeric values.
        Code:
        clear all
        cls
        // data from post #1
        * Example generated by -dataex-. To install: ssc install dataex
        clear
        input str50 var1 int var2 str50 var3 float var4
        "Sarita"            25 "Geeta"          23.1
        "mushkanchan"       31 "Subha"          18.9
        "Kanchandeviparmer" 21 "Kamla"          81.3
        "Laxmi"             23 "Subhaparmar"    27.1
        "Ram"               21 "Sarita"           23
        "Sita"              22 "Subha"            34
        "Haru"              18 "Santosh"          22
        "hari kana"         23 "Santosh K Dash" 23.5
        end
        ds var1-var4, has(type string)
        format %50s `r(varlist)'
        ds var1-var4, has(type numeric)
        format %20.0g `r(varlist)'
        describe
        Code:
        . ds var1-var4, has(type string)
        var1  var3
        
        . format %50s `r(varlist)'
        
        . ds var1-var4, has(type numeric)
        var2  var4
        
        . format %20.0g `r(varlist)'
        
        . describe
        
        Contains data
          obs:             8                          
         vars:             4                          
        ------------------------------------------------------------------------------------------------
                      storage   display    value
        variable name   type    format     label      variable label
        ------------------------------------------------------------------------------------------------
        var1            str50   %50s                  
        var2            int     %20.0g                
        var3            str50   %50s                  
        var4            float   %20.0g                
        ------------------------------------------------------------------------------------------------
        Sorted by: 
             Note: Dataset has changed since last saved.
        
        .

        Comment


        • #5

          Thank you. It solved my problem.

          Comment


          • #6
            William Lisowski solved the problem. Meanwhile, let's rewrite #3 so that it works. The intent is

            loop over a set of variables {

            if a variable is string format it one way

            otherwise format it another way

            }

            The idea is one loop over variables, whereas the ds solution -- which I like greatly for various reasons and would have posted had William Lisowski not got there first -- does entail two loops. But in practice it would take most programmers more time to think up a single loop and get it working than is wasted by using ds.

            Here is the idea implemented:

            Code:
            clear all
            input str50 var1 int var2 str50 var3 float var4
            whatisyourname    20  whatisyourname   22.4
            Sarita            25  Geeta            23.1
            mushkanchan       31  Subha            18.9
            Kanchandeviparmer 21  Kamla            81.3
            Laxmi             23  Subhaparmar      27.1
            Ram               21  Sarita           23
            Sita              22  Subha            34
            Haru              18  Santosh          22
            "hari kana"       23  "Santosh K Dash" 23.5
            end
            
            
            foreach var of varlist var1-var4 {
                capture confirm str variable `var'
                if _rc == 0 format `var' %50s 
                else format `var' %20.0g 
            }

            Here are some of the problems with #3.

            1. format needs to be told the name of one or more variables.

            2. %50s was not the right format in both cases.

            3. word # of seems misunderstood.

            4. A test of a macro against an existing variable name would be more like if "`j'" == "`var'", noting the syntax to evaluate macros, the == sign and the use of "".

            5. A single variable name can't possibly be equal to a list of two variable names.

            Comment


            • #7
              Nick Cox Thank you for correcting the looping code. Thank you for highlighting the mistakes in #3.

              Comment

              Working...
              X