Search code examples
filesaskeyvaluepairdatastep

create "pair key=value" file with SAS datastep


I have to create a file from a dataset that is JSON style but without CR between each variable. All variables have to be on the same line.

I would like to have something like that :

ID1 "key1"="value1" "key2"="value2" .....

Each key is a column of a dataset. I work this SAS 9.3 on UNIX.

Sample : I have

ID Name Sex Age
123 jerome M 30
345 william M 26
456 ingrid F 25`

I would like

123 "Name"="jerome" "sex"="M" "age"="30"
345 "Name"="william" "sex"="M" "age"="26"
456 "Name"="ingrid" "sex"="F" "age"="25"

Thanks


Solution

  • Consider these non-transposing variations:

    Actual JSON, use Proc JSON

    data have;input
    ID Name $ Sex $ Age; datalines;
    123 jerome M 30
    345 william M 26
    456 ingrid F 25
    run;
    
    filename out temp;
    proc json out=out;
      export have;
    run;
    
    * What hath been wrought ?;
    data _null_; infile out; input; put _infile_; run;
    
    ----- LOG -----
    
    {"SASJSONExport":"1.0","SASTableData+HAVE":[{"ID":123,"Name":"jerome","Sex":"M","Age":30},{"ID":345,"Name":"william","Sex":"M","Age":26},{"ID":456,"Name":"ingrid","Sex":"F","Age":25}]}
    

    A concise name-value pair output of the variables using the PUT statement specification syntax (variable-list) (format-list), using _ALL_ for the variable list and = for the format.

    filename out2 temp;
    data _null_;
      set have;
      file out2;
      put (_all_) (=);
    run;
    
    data _null_;
      infile out2; input; put _infile_;
    run;
    
    ----- LOG -----
    
    ID=123 Name=jerome Sex=M Age=30
    ID=345 Name=william Sex=M Age=26
    ID=456 Name=ingrid Sex=F Age=25
    

    Iterate the variables using the VNEXT routine. Extract the formatted values using VVALUEX function, and conditionally construct the quoted name and value parts.

    filename out3 temp;
    data _null_;
      set have;
      file out3;
    
      length _name_ $34 _value_ $32000;
    
      do _n_ = 1 by 1;
        call vnext(_name_);
        if _name_ = "_name_" then leave;
        if _n_ = 1 
          then _value_ =       strip(vvaluex(_name_));
          else _value_ = quote(strip(vvaluex(_name_)));
        _name_ = quote(trim(_name_));
        if _n_ = 1 
          then put _value_ @;
          else put _name_ +(-1) '=' _value_ @;
      end;
      put;
    run;
    
    data _null_;
      infile out3; input; put _infile_;
    run;
    
    ----- LOG -----
    
    123 "Name"="jerome" "Sex"="M" "Age"="30"
    345 "Name"="william" "Sex"="M" "Age"="26"
    456 "Name"="ingrid" "Sex"="F" "Age"="25"