BookmarkSubscribeRSS Feed
melhaf
Fluorite | Level 6

Hi, 

¨Why don¨'t strawberry print out in this code? (this is just fiction dataset that I created, they don't both come from WORK. Banana comes from ex libname Africa, and strawberry from UK. So I want to have them seperated. Thanks! 

 

data banana;
    length banana 8 fruit 8;
    do year = 2014 to 2023;
        date = input(cats(put(year, 4.), '1231'), yymmdd8.);
        do i = 1 to 25;
            customer = cats('Customer', (year - 2014) * 25 + i);
            banana = round(ranuni(0) * 100, 0.01); 
            fruit = ceil(ranuni(0) * 2) - 1;
            output;
            if i <= 10 then do;
                customer = cats('Customer', (year - 2014) * 25 + i);
                banana = round(ranuni(0) * 100, 0.01); 
                fruit = ceil(ranuni(0) * 2) - 1; 
                output;
            end;
        end;
    end;
    format date yymmddn8.;
    drop i year;
run;



data strawberry;
    length strawberry 8 fruit 8;
    do year = 2014 to 2023;
        date = input(cats(put(year, 4.), '1231'), yymmdd8.);
        do i = 1 to 25;
            customer = cats('Customer', (year - 2014) * 25 + i);
            banana = round(ranuni(0) * 100, 0.01); 
            fruit = ceil(ranuni(0) * 2) - 1;
            output;
            if i <= 10 then do;
                customer = cats('Customer', (year - 2014) * 25 + i);
                strawberry = round(ranuni(0) * 100, 0.01); 
                fruit = ceil(ranuni(0) * 2) - 1; 
                output;
            end;
        end;
    end;
    format date yymmddn8.;
    drop i year;
run;



%macro check_column_types(libname=, memname=,);
    proc contents data=&libname..&memname out=columns_info(keep=name type);
    run;

    /* Skapa temp-dataset */
    data column_types;
        set columns_info;
/*ATTRN (en sas-funktion som används för att hämta attribut för en variabel i ett dataset)  bestämemer datatypen*/
        array char_cols[*] _character_;
        array num_cols[*] _numeric_;
        do i = 1 to dim(char_cols);
            if vname(char_cols[i]) = name then do;
                column_type = 'CHAR';
                output;
            end;
        end;
        do i = 1 to dim(num_cols);
            if vname(num_cols[i]) = name then do;
                column_type = 'NUM';
                output;
            end;
        end;
    run;

    proc print data=column_types noobs;
        title 'BANANA NNANANBANANABNASBA';
    run;
    
    /* Rensa temp-datasets */
    proc datasets library=work nolist;
        delete columns_info column_types;
    quit;
%mend;
%check_column_types(libname=work, memname=banana);


%macro check_column_types(libname=, memname=,);
    proc contents data=&libname..&memname out=columns_info(keep=name type);
    run;

    /* Skapa temp-dataset */
    data column_types;
        set columns_info;
/*ATTRN (en sas-funktion som används för att hämta attribut för en variabel i ett dataset)  bestämemer datatypen*/
        array char_cols[*] _character_;
        array num_cols[*] _numeric_;
        do i = 1 to dim(char_cols);
            if vname(char_cols[i]) = name then do;
                column_type = 'CHAR';
                output;
            end;
        end;
        do i = 1 to dim(num_cols);
            if vname(num_cols[i]) = name then do;
                column_type = 'NUM';
                output;
            end;
        end;
    run;

    proc print data=column_types noobs;
        title 'STRAWBERRY BERYRYEYRYRWEBERBE';
    run;
    
    /* Rensa temp-datasets */
    proc datasets library=work nolist;
        delete columns_info column_types;
    quit;
%mend;

%check_column_types(libname=work, memname=strawberry);
18 REPLIES 18
yabwon
Onyx | Level 15

Can you tell us what do you want to get with your code? It would be easier to figure it out.

 

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



melhaf
Fluorite | Level 6

Hi Bart, 

Have you runned the code?

 

title 'STRAWBERRY BERYRYEYRYRWEBERBE';

 

 

dosen't print

yabwon
Onyx | Level 15

Just checking, do you want to get something like this?

%macro check_column_types(libname=, memname=);
    title "Libname: &libname., data set: &memname";
    /*ods trace on;*/
    ods select Variables;
    proc contents 
      data=&libname..&memname 
    ;
    run;
    ods select all;
    /*ods trace off;*/
%mend;


%check_column_types(libname=work, memname=banana)
%check_column_types(libname=work, memname=strawberry)

%check_column_types(libname=sashelp, memname=class)

 

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



melhaf
Fluorite | Level 6

I want my code to work tbh

PaigeMiller
Diamond | Level 26

Agreeing with @yabwon I think you are working very hard to do something simple, but its not clear what you are trying to do. Please explain the goal of this block of code — explain in words, do not explain by talking about code.

 

Your IF statements fail. For i=1

 

if vname(char_cols[i]) = name then do;

 

 

tries to check the variable name of the first character variable is equal to the value of variable name. Just writing this sentence and getting it to mean what I think you are doing is confusing. But, it is checking to see if the text string containing the first variable of char_chols, which is the string 'NAME', is equal to the values in the variable NAME, and those values are banana, customer, date and fruit. So 'NAME' is never equal to those values. So the IF statement never  succeeds, and so nothing ever gets sent to OUTPUT; and there is nothing to print.

 

Now explain what you are trying to do. Do not discuss code in your explanation.


Also, despite your title implying this is a macro error, it is not a macro error. It is a data step that doesn't do what you want it to do. Which brings us to IMPORTANT ADVICE: do not try to write a macro until you have non-macro code working. You didn't do that, so you will find it very difficult to get a macro to work. Write non-macro code and get it to work first.

--
Paige Miller
ballardw
Super User

If you want to see the names and types of variables then perhaps:

 

 

proc print data=sashelp.vcolumn noobs;
   where libname='SASHELP' and memname='CLASS';
   var name type;
run;

 

 

Your only numeric variable in the columns_info is Type. Which will have values of 1 or 2. Which is unlikely to be any sort of "name". So I suspect this bit of code is especially useless:

        do i = 1 to dim(num_cols);
            if vname(num_cols[i]) = name then do;
                column_type = 'NUM';
                output;
            end;
        end;

If you are looking to the type of a specific variable then you have not provided the name of that variable anywhere unless you are expecting MEMNAME to be both the name of a data set and the name of a variable.

melhaf
Fluorite | Level 6

but still why dosne't my code work?

Reeza
Super User

Taking your question at face value. 

 

From the log:

 

NOTE: No observations in data set WORK.COLUMN_TYPES.
NOTE: PROCEDURE PRINT used (Total process time)
Therefore the title does not print. 
 
 
If you want that title printed regardless, try ODS TEXT= or PROC ODSTEXT to generate the text. 
 
As others have indicated, needing to redefine a macro is bad practice and likely means you need to add another parameter to your macro (e.g. TITLE to have your title included dynamically)
 
Spoiler

@melhaf wrote:

Hi, 

¨Why don¨'t strawberry print out in this code? (this is just fiction dataset that I created, they don't both come from WORK. Banana comes from ex libname Africa, and strawberry from UK. So I want to have them seperated. Thanks! 

 

data banana;
    length banana 8 fruit 8;
    do year = 2014 to 2023;
        date = input(cats(put(year, 4.), '1231'), yymmdd8.);
        do i = 1 to 25;
            customer = cats('Customer', (year - 2014) * 25 + i);
            banana = round(ranuni(0) * 100, 0.01); 
            fruit = ceil(ranuni(0) * 2) - 1;
            output;
            if i <= 10 then do;
                customer = cats('Customer', (year - 2014) * 25 + i);
                banana = round(ranuni(0) * 100, 0.01); 
                fruit = ceil(ranuni(0) * 2) - 1; 
                output;
            end;
        end;
    end;
    format date yymmddn8.;
    drop i year;
run;



data strawberry;
    length strawberry 8 fruit 8;
    do year = 2014 to 2023;
        date = input(cats(put(year, 4.), '1231'), yymmdd8.);
        do i = 1 to 25;
            customer = cats('Customer', (year - 2014) * 25 + i);
            banana = round(ranuni(0) * 100, 0.01); 
            fruit = ceil(ranuni(0) * 2) - 1;
            output;
            if i <= 10 then do;
                customer = cats('Customer', (year - 2014) * 25 + i);
                strawberry = round(ranuni(0) * 100, 0.01); 
                fruit = ceil(ranuni(0) * 2) - 1; 
                output;
            end;
        end;
    end;
    format date yymmddn8.;
    drop i year;
run;



%macro check_column_types(libname=, memname=,);
    proc contents data=&libname..&memname out=columns_info(keep=name type);
    run;

    /* Skapa temp-dataset */
    data column_types;
        set columns_info;
/*ATTRN (en sas-funktion som används för att hämta attribut för en variabel i ett dataset)  bestämemer datatypen*/
        array char_cols[*] _character_;
        array num_cols[*] _numeric_;
        do i = 1 to dim(char_cols);
            if vname(char_cols[i]) = name then do;
                column_type = 'CHAR';
                output;
            end;
        end;
        do i = 1 to dim(num_cols);
            if vname(num_cols[i]) = name then do;
                column_type = 'NUM';
                output;
            end;
        end;
    run;

    proc print data=column_types noobs;
        title 'BANANA NNANANBANANABNASBA';
    run;
    
    /* Rensa temp-datasets */
    proc datasets library=work nolist;
        delete columns_info column_types;
    quit;
%mend;
%check_column_types(libname=work, memname=banana);


%macro check_column_types(libname=, memname=,);
    proc contents data=&libname..&memname out=columns_info(keep=name type);
    run;

    /* Skapa temp-dataset */
    data column_types;
        set columns_info;
/*ATTRN (en sas-funktion som används för att hämta attribut för en variabel i ett dataset)  bestämemer datatypen*/
        array char_cols[*] _character_;
        array num_cols[*] _numeric_;
        do i = 1 to dim(char_cols);
            if vname(char_cols[i]) = name then do;
                column_type = 'CHAR';
                output;
            end;
        end;
        do i = 1 to dim(num_cols);
            if vname(num_cols[i]) = name then do;
                column_type = 'NUM';
                output;
            end;
        end;
    run;

    proc print data=column_types noobs;
        title 'STRAWBERRY BERYRYEYRYRWEBERBE';
    run;
    
    /* Rensa temp-datasets */
    proc datasets library=work nolist;
        delete columns_info column_types;
    quit;
%mend;

%check_column_types(libname=work, memname=strawberry);

 
melhaf
Fluorite | Level 6

but it s print for banana

Reeza
Super User

 


@melhaf wrote:

but it s print for banana


No it doesn't. At least not within that procedure. It prints it at the next proc contents. 

 

Title remains valid until you overwrite it with another title statement or set it to blank and that's what you're seeing. Re-order your code to see that correctly. 

 

data banana;
    length banana 8 fruit 8;
    do year = 2014 to 2023;
        date = input(cats(put(year, 4.), '1231'), yymmdd8.);
        do i = 1 to 25;
            customer = cats('Customer', (year - 2014) * 25 + i);
            banana = round(ranuni(0) * 100, 0.01); 
            fruit = ceil(ranuni(0) * 2) - 1;
            output;
            if i <= 10 then do;
                customer = cats('Customer', (year - 2014) * 25 + i);
                banana = round(ranuni(0) * 100, 0.01); 
                fruit = ceil(ranuni(0) * 2) - 1; 
                output;
            end;
        end;
    end;
    format date yymmddn8.;
    drop i year;
run;





%macro check_column_types(libname=, memname=,);
    proc contents data=&libname..&memname out=columns_info(keep=name type);
    run;

    /* Skapa temp-dataset */
    data column_types;
        set columns_info;
/*ATTRN (en sas-funktion som används för att hämta attribut för en variabel i ett dataset)  bestämemer datatypen*/
        array char_cols[*] _character_;
        array num_cols[*] _numeric_;
        do i = 1 to dim(char_cols);
            if vname(char_cols[i]) = name then do;
                column_type = 'CHAR';
                output;
            end;
        end;
        do i = 1 to dim(num_cols);
            if vname(num_cols[i]) = name then do;
                column_type = 'NUM';
                output;
            end;
        end;
    run;

    proc print data=column_types noobs;
        title 'BANANA NNANANBANANABNASBA';
    run;
    
    /* Rensa temp-datasets */
    proc datasets library=work nolist;
        delete columns_info column_types;
    quit;
%mend;
%check_column_types(libname=work, memname=banana);



data strawberry;
    length strawberry 8 fruit 8;
    do year = 2014 to 2023;
        date = input(cats(put(year, 4.), '1231'), yymmdd8.);
        do i = 1 to 25;
            customer = cats('Customer', (year - 2014) * 25 + i);
            banana = round(ranuni(0) * 100, 0.01); 
            fruit = ceil(ranuni(0) * 2) - 1;
            output;
            if i <= 10 then do;
                customer = cats('Customer', (year - 2014) * 25 + i);
                strawberry = round(ranuni(0) * 100, 0.01); 
                fruit = ceil(ranuni(0) * 2) - 1; 
                output;
            end;
        end;
    end;
    format date yymmddn8.;
    drop i year;
run;

%macro check_column_types(libname=, memname=,);
    proc contents data=&libname..&memname out=columns_info(keep=name type);
    run;

    /* Skapa temp-dataset */
    data column_types;
        set columns_info;
/*ATTRN (en sas-funktion som används för att hämta attribut för en variabel i ett dataset)  bestämemer datatypen*/
        array char_cols[*] _character_;
        array num_cols[*] _numeric_;
        do i = 1 to dim(char_cols);
            if vname(char_cols[i]) = name then do;
                column_type = 'CHAR';
                output;
            end;
        end;
        do i = 1 to dim(num_cols);
            if vname(num_cols[i]) = name then do;
                column_type = 'NUM';
                output;
            end;
        end;
    run;

    proc print data=column_types noobs;
        title 'STRAWBERRY BERYRYEYRYRWEBERBE';
    run;
    
    /* Rensa temp-datasets */
    proc datasets library=work nolist;
        delete columns_info column_types;
    quit;
%mend;

%check_column_types(libname=work, memname=strawberry);

 

Tom
Super User Tom
Super User

The most basic reason is because you are defining the arrays using the variables in COLUMNS_INFO (the proc contents output dataset) and not the variables in the dataset that you ran PROC CONTENTS on to create the COLUMNS_INFO dataset.

 

For example for WORK.BANANA the set of variables is:

#    Variable    Type    Len    Format
1    banana      Num       8
2    fruit       Num       8
3    date        Num       8    YYMMDDN8.
4    customer    Char    200

But for COLUMNS_INFO the set of variables is:

#    Variable    Type    Len    Label
1    NAME        Char     32    Variable Name
2    TYPE        Num       8    Variable Type

And the content of COLUMNS_INFO is:

Obs    NAME        TYPE
 1     banana        1
 2     customer      2
 3     date          1
 4     fruit         1

So when you run this code:

data column_types;
  set columns_info;
  array char_cols[*] _character_;
  array num_cols[*] _numeric_;

Both arrays will have only one variable in them.  NAME for CHAR_COLS and TYPE for NUM_COLS.

 

If you wanted those arrays to have variables like CUSTOMER or BANANA in them then you would have needed to have referenced WORK.BANANA before the ARRAY statements.

 

So perhaps the data step could start like this:

data column_types;
  if 0 then do;
    set &libname..&memname ;
    array char_cols[*] _character_;
    array num_cols[*] _numeric_;
  end;
  set columns_info;

But note that will cause all kinds of trouble. What happens if the database being checked has a CHARACTER variable name TYPE?  That will cause a compile time error for the data step since TYPE is numeric in the  COLUMNS_INFO dataset.  You cannot have the same variable with two different types in the same dataset.

 

Is there something you are actually trying to do with these macros (and why did you define the same macro twice? Are there any differences between the two copies of the macro definition?)  Can you explain?

 

Because it really just looks like you are trying to make character variable the the TYPE value as NUM or CHAR instead of numeric values that the TYPE variable generated by PROC CONTENTS has.

data column_types;
  set columns_info;
  if type=2 then column_type = 'CHAR';
  else column_type = 'NUM';
run;

Or perhaps even easier just make a format that maps 1 to NUM and 2 to CHAR and attach it to TYPE and the 1 and 2 will print as NUM and CHAR.  Perhaps something like this??

%macro check_column_types_3(libname,memname);
proc contents noprint data=&libname..&memname out=columns_info(keep=name type);
run;

proc format ;
  value ctype 1='Num' 2='Char';
run;

proc print data=columns_info;
 format type ctype.;
 title 'STRAWBERRY BERYRYEYRYRWEBERBE';
run;

proc delete data=columns_info;
run;

%mend check_column_types_3;
%check_column_types_3(libname=work,memname=strawberry);
melhaf
Fluorite | Level 6
I just don't get... whyyyy cant it print both strawberry and banana?
melhaf
Fluorite | Level 6

But Banana is still coming from another dataste then strawberry. Sorry, but I seriously don't get 

PaigeMiller
Diamond | Level 26

@melhaf wrote:

But Banana is still coming from another dataste then strawberry. Sorry, but I seriously don't get 


We have asked you to explain what your code is supposed to be doing. Explain in words, give us the big picture, why are you doing this. Without this explanation, I don't see any point in going further into this problem. Figuring out your actual code is not a good path forward. There is undoubtedly a much easier way to do this, and if we knew what you are trying to do, we could show you that much easier way to do this.

 

In your earlier thread about mean, median, min, max it was much easier to figure out what you were doing, and an alternative set of code which was much simpler was provided. Tell us what you are trying to do!

--
Paige Miller

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 18 replies
  • 1692 views
  • 2 likes
  • 6 in conversation