Dynamic variable names in SAS

2020-04-14 01:18发布

问题:

Is there a way in SAS to specify dynamic variable names in code? i.e. use different variables on different observations based on the value of another variable?

For example, my input data set could be:

Index  Var1   Var2  Var3
1      78.3   54.7  79.8
3      67.2   56.2  12.3
2      65.3   45.2  98.1
1      56.2   49.7  11.3
1      67.2   98.2  98.6

And I want to add a column that holds the value of Var*Index*. i.e. the output I'd want would be:

    Index  Var1   Var2  Var3  Var_Index
    1      78.3   54.7  79.8  78.3
    3      67.2   56.2  12.3  12.3
    2      65.3   45.2  98.1  45.2
    1      56.2   49.7  11.3  56.2
    1      67.2   98.2  98.6  67.2

I'm unable to use call symput to get this to work. Also I should mention that my real problem is slightly more complicated, and I already have a messy brute force method but I'm looking for something clean.

回答1:

If you create an array of Var1 - VarN then you can easily reference the value stored in Index.

data have;
input Index  Var1   Var2  Var3;
cards;
1      78.3   54.7  79.8
3      67.2   56.2  12.3
2      65.3   45.2  98.1
1      56.2   49.7  11.3
1      67.2   98.2  98.6
;
run;

data want;
set have;
array vars(*) var: ;
var_index=vars(index);
run;


回答2:

I think the simplest solution would be to use VVALUEX function. It creates the variable name using the index, and then supplies it as an argument to the function -

var_index = vvaluex(compress("var" || put(index, 8.)));


回答3:

Wouldn't a data step work?

 data assign_value;
  set have;

  if index = 1 then var_index = var1;
  else if index = 2 then var_index = var2;
  else if index = 3 then var_index = var3;
run;

I might be missing something? but this should give you the result from your question.



回答4:

data want;
    set have;
    length _var_name $32 _var_num 5;
    array vars(*) var: ;
    /* if you want name of variable */
    _var_name=VNAME(vars(index));
    /* if you want numeric suffix of variable 
            and suffix is not same as position of variable in array
          (so that vars(index) is not usable */
    _var_num=INPUT(SUBSTR(_var_name, ANYDIGIT(_var_name)),32.);
run;

So what you need is VNAME() function.