BookmarkSubscribeRSS Feed
data_null__
Jade | Level 19
> In fairness, polingjw did state, “Of course, this
> code will produce an error due to the syntax of
> “first.variables{i}.” ”
I did go on to say "as you have determined".

>
> J.D.’s code above works, as does data _null_’s
> (although purists (I’d say prudes) might complain
> about the WARNING: note in data _null_’s SAS .log).

Thanks for pointing out the WARNING. I had changed the variable B to FIRST but forgot to change the OUTPUT statement where I defined CVALS. No warning now.
jdopdyke
Calcite | Level 5
Agreed – data _null_’s is a nice solution.

But J.D.’s is more general. For example, it can mix variable types amongst the by-variables, which is not a terribly infrequent occurrence.
data_null__
Jade | Level 19
> But J.D.’s is more general. For example, it can mix
> variable types amongst the by-variables, which is not
> a terribly infrequent occurrence.

I would say BY variables lists of mixed data types is the norm. The BY variable TYPE is not an issue. The ARRAY is of FIRSTdot variables which are always numeric. My corrected example illustrates this as the variable FIRST is defined as a character variable.
jdopdyke
Calcite | Level 5
Actually, in your (data _null_'s) first posting, “first” is a numeric variable (because you hadn’t swapped b for “first”).

But in your second posting, you are correct – apologies. My comment is only true of Chung’s rewrite of your code, and mine is more general than Chung’s rewrite.

As an aside, when possible I try not to mix types, so I’ve seen it more frequently when I’m forced to inherit others’ code.
data_null__
Jade | Level 19
> Actually, in your (data _null_'s) first posting,
> “first” is a numeric variable (because you hadn’t
> swapped b for “first”).
Yes, that's what I said. But it is still irrelevant. The data type of the BY variable is not the issue.
>
> But in your second posting, you are correct –
> apologies. My comment is only true of Chung’s
> rewrite of your code, and mine is more general than
> Chung’s rewrite.
Perhaps, but you have not defined an array of first variables. If would rather have seen a macro to write an ARRAY statement, that's what the OP was looking for.

[pre]array f
  • first.a first.b first.c;[/pre]


    > As an aside, when possible I try not to mix types, so
    > I’ve seen it more frequently when I’m forced to
    > inherit others’ code.
    You misunderstand me, I was saying it is normal to have BY variables that have different data types. As in my example. A is numeric, First is character, C is numeric. Very common and not a problem.
  • jdopdyke
    Calcite | Level 5
    1) GENERALITY OF CODE: If in your experience groups of BY variables are often of mixed types (numeric and character), then what I’m saying is true: my code is more general than Chung’s rewrite of your code, since his does not allow the by-variables to be of mixed (numeric and character) types (because he uses an ARRAY statement). Not “perhaps,” just a simple SAS fact.

    2) UNDERSTANDING: I understood exactly what you’re saying: yes, of course, as a general rule groups of BY variables of different types (numeric and character) can be used on BY or CLASS statements. Since my code handles that, clearly I did not think it was terribly uncommon, nor did I think it was a problem generally.

    However, there are cases where it can be a problem, so without pulling any muscles, I try to remain cognizant of that generally and generally try to avoid mixing. For example, I often use a macro variable to contain the names of a group of BY variable names (as I did in my macro – very common). But if I wanted to perform some repetitive operation on them in a data step, an ARRAY would be a likely choice, but I could not do so in an ARRAY statement if they are of mixed TYPEs.

    That’s just one example, so if a string of variable names are being used in macro variable, mixing the types CAN be a problem. So to the extent that it can trip up the unsuspecting code, it IS relevant.

    3) FORCING A SOLUTION TO USE ARRAYS: I think you are taking polingjw’s request way too literally. Polingjw is the only person who can confirm or deny this, but it was clear to me that s/he was more familiar with arrays and so wrote the “conceptual code” using arrays only to make the point (hence the disclaimer) that s/he wanted to process by-variables succinctly, but did not necessarily need the solution literally to use arrays. Rather, “Does anyone have any alternatives to make this code work?” to me means solve the problem of executing some code whenever hitting a first.var value. I whether or not a solution uses arrays is irrelevant.
    data_null__
    Jade | Level 19
    > 1) GENERALITY OF CODE: If in your experience groups
    > of BY variables are often of mixed types (numeric and
    > character), then what I’m saying is true: my code is
    > more general than Chung’s rewrite of your code, since
    > his does not allow the by-variables to be of mixed
    > (numeric and character) types (because he uses an
    > ARRAY statement). Not “perhaps,” just a simple SAS
    > fact.

    It is clear that you don't understand how the programs presented by me and Chang work. The ARRAY is NOT an array of BY variables it is an ARRAY of FIRST variables. The data type of the BY variables is irrelevant.

    There is potential for a problem using [pre]array f
  • first:;[/pre]vs[pre]array f
  • 'first.'n:[/pre]the former having the possibility to include other variables that begin with FIRST that are not FIRSTdot. Both statements are shorthand for.
    [pre]array f
  • first.a first.b first.c;[/pre]

    > 2) UNDERSTANDING: I understood exactly what you’re
    > saying: yes, of course, as a general rule groups of
    > BY variables of different types (numeric and
    > character) can be used on BY or CLASS statements.
    > Since my code handles that, clearly I did not think
    > it was terribly uncommon, nor did I think it was a
    > problem generally.
    >
    > However, there are cases where it can be a problem,
    > so without pulling any muscles, I try to remain
    > cognizant of that generally and generally try to
    > avoid mixing. For example, I often use a macro
    > variable to contain the names of a group of BY
    > variable names (as I did in my macro – very common).
    > But if I wanted to perform some repetitive operation
    > on them in a data step, an ARRAY would be a likely
    > choice, but I could not do so in an ARRAY statement
    > if they are of mixed TYPEs.
    >
    > That’s just one example, so if a string of variable
    > names are being used in macro variable, mixing the
    > types CAN be a problem. So to the extent that it can
    > trip up the unsuspecting code, it IS relevant.

    You still don't get it. Why should BY variable TYPE matter. I do not have control over the TYPE of any variable that is not created by my program including the variables used in BY statements. Why should any program macro of otherwise ever by "tripped up" because one BY variable is numeric and another is character.

    >
    > 3) FORCING A SOLUTION TO USE ARRAYS: I think you are
    > taking polingjw’s request way too literally.
    > Polingjw is the only person who can confirm or deny
    > this, but it was clear to me that s/he was more
    > familiar with arrays and so wrote the “conceptual
    > code” using arrays only to make the point (hence the
    > disclaimer) that s/he wanted to process by-variables
    > succinctly, but did not necessarily need the
    > solution literally to use arrays. Rather, “Does
    > anyone have any alternatives to make this code
    > work?” to me means solve the problem of executing
    > some code whenever hitting a first.var value. I
    > whether or not a solution uses arrays is irrelevant.

    I'm not forcing anyone to do anything. I was answering the question. You're the one going on about how your macros are better, while still not understanding the program I wrote. It appears that you do not fully understand what a FIRSTdot variable is and how it can be used.
  • polingjw
    Quartz | Level 8
    In my actual program I only want to include those variables with the prefix “gen” in the array but there are a number of additional variables listed in the by statement. The array statement I’m going to use is

    [pre]

    array firstgen{*} ‘first.gen’n:;
    [/pre] [pre]
    [/pre]
    Therefore, I actually do need the validvarname=any option for my program to work. Thanks again for this great solution!
    jdopdyke
    Calcite | Level 5
    You’re incorrect, as a factual matter, on all three counts.

    Below is Chung’s original posting (I copied it to run it) – unfortunately, its been changed in the history of the thread.

    He did, in fact, use an array for the by variables. It wasn’t a big deal, but if somebody was embarrassed enough to change the thread (how sad), then there’s no use discussing it further.

    proc plan ordered;
    factors var1=2 var2=2 var3=3 / noprint;
    output out=old;
    run;
    quit;

    data new;
    set old;
    by var:;
    array vars(*) var:;
    array firsts(*) first:;

    drop i;
    do i = 1 to dim(vars);
    put firsts(i) 2. @;
    end;
    put;
    run;

    proc print; run;

    Everything else you wrote I agree with, except for your claims that I’m misunderstanding. I’ve said several times now that I was just making a general statement about not mixing variable TYPEs because SOMETIMES, if you’re using a list of variable names in a macro variable (whether or not they’re by variables), it can lead to problems. I used the example of an ARRAY statement, and Chung’s (original) rewrite of your code, to prove my point. But again, if folks are going to try to change threads, then no use in going further. Thanks for your posting.
    jdopdyke
    Calcite | Level 5
    Thank YOU for a posting that GENerated such interest! (homonymic pun's are excusable if you haven't had morning coffee yet...)

    SAS Innovate 2025: Save the Date

     SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

    Save the date!

    How to Concatenate Values

    Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

    Find more tutorials on the SAS Users YouTube channel.

    SAS Training: Just a Click Away

     Ready to level-up your skills? Choose your own adventure.

    Browse our catalog!

    Discussion stats
    • 24 replies
    • 3033 views
    • 0 likes
    • 6 in conversation