通过数据步连接 SAS 变量

发布于 2024-11-04 02:14:18 字数 1157 浏览 0 评论 0原文

我正在寻找一种方法来创建包含数据集某些值的字符串变量,同时执行数据步骤。

示例数据集 work.test:

AddToStringYN    Value
     Y           One
     Y           Two
     N           Three
     Y           Four
     N           Five

所以最终,变量将如下所示:OneTwoFour(或者更好的 FourTwoOne)。 这看起来很简单,但我似乎找不到办法。 我还尝试使用这样的宏变量:

%let stringvar=;
Data _null_;
  set work.test;
  if AddToStringYN = "Y" then do;
    call symput('stringvar',"&stringvar" || strip(value));
  end;
Run;

但这给出:

GLOBAL STRINGVAR Four

所以我只得到最后一个值。我知道这一定是因为我对这个宏设施的一些误解,但我不明白为什么变量中只有最后一个值。 我以为只有最后一次调用 symput 时它才实际执行或其他什么,但是当我将代码调整为:

%let stringvar=;
Data _null_;
  set work.test;
  if AddToStringYN = "Y" then do;
    call symput('stringvar'||strip(value),"&stringvar" || strip(value));
  end;
Run;

然后我确实得到了它们全部:

GLOBAL STRINGVARONE  One
GLOBAL STRINGVARTWO  Two
GLOBAL STRINGVARFOUR  Four

所以我最后的猜测是,通过数据步骤,' call symput...' 行实际上被添加到宏处理器中,其中“&stringvar”已被替换,并且只有在最终语句之后它们才会全部执行。
这是一个很好的假设还是有其他解释? 回到最初的问题:有没有一种简单的方法可以实现这一点(拥有所需的变量)?

I am looking for a way to create a string variable containing certain values of the dataset while going through the data step.

Example data set work.test:

AddToStringYN    Value
     Y           One
     Y           Two
     N           Three
     Y           Four
     N           Five

So in the end, the variable would look like: OneTwoFour (or even better FourTwoOne).
This looks so simple, but I can't seem to find a way to do it.
I also tried to work with macro variables like this:

%let stringvar=;
Data _null_;
  set work.test;
  if AddToStringYN = "Y" then do;
    call symput('stringvar',"&stringvar" || strip(value));
  end;
Run;

But this gives:

GLOBAL STRINGVAR Four

So I only get the last value. I get that this must be because of some misunderstanding of mine about this macro facility, but I don't understand why there is only the last value in the variable.
I thought it was only the last time the symput was called that it was actually executed or something, but then when I adjust the code to:

%let stringvar=;
Data _null_;
  set work.test;
  if AddToStringYN = "Y" then do;
    call symput('stringvar'||strip(value),"&stringvar" || strip(value));
  end;
Run;

Then I do get them all:

GLOBAL STRINGVARONE  One
GLOBAL STRINGVARTWO  Two
GLOBAL STRINGVARFOUR  Four

So my last guess is that going through the data step, the 'call symput...' line is actually added to the macro processor where the "&stringvar" is already replaced and only after the final statement are they all executed.
Is this a good assumption or is there another explanation?
And back to the original question: is there an easy way to achieve this (having the desired variable)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半衬遮猫 2024-11-11 02:14:18

以下是我对 您在 RunSubmit.com 上的相同问题的回答。我认为你和@Fabio可能过度设计了解决方案,它根本不需要任何迭代数据步骤代码......

首先,做你想做的事情的简单方法是这样的:

proc sql;
  select Value into :StringVar separated by ''
    from work.test
    where AddToStringYN='Y'
    ;
quit;

在这里,你可以使用 select into 语法利用 SAS/MACRO 的 SQL 接口。您甚至可以添加 order by 子句来获取您要查找的特定订单。

其次,由于您已经了解了 SAS 宏的工作方式,并且您很想了解它:在第一个示例中,编译器在执行代码之前所做的第一件事是解析 & 的值。 stringvar,此时它是空的。因此,编译后,替换此标记后,您的代码在 SAS 中看起来像这样...

%let stringvar=;
Data _null_;
  set work.test;
  if AddToStringYN = "Y" then do;
    call symput('stringvar',"" || strip(value));
  end;
Run;

...然后 SAS 继续运行该代码(这恰好是有效代码,但将一个空字符串连接到某些内容的开头) 。由于数据步骤的工作方式,数据步骤的每次迭代实际上都会替换 StringVar 的值,这就是为什么在数据步骤结束时,留下了最后一个值被读入。

The following is my answer to your identical question on RunSubmit.com. I think you and @Fabio may be over-engineering the solution, it doesn't need any iterating data step code at all...

First, the easy way to do what you're trying to do is like this:

proc sql;
  select Value into :StringVar separated by ''
    from work.test
    where AddToStringYN='Y'
    ;
quit;

Here, you can take advantage of the SQL interface with SAS/MACRO, using the select into syntax. You could even add an order by clause to get a particular order you're looking for.

Second, since you've happened upon something about the way SAS macro works and you're keen to understand it: in your first example, the first thing the compiler does before executing your code is to resolve the value of &stringvar, which at that point is empty. So after compilation, with this token replaced, your code looks like this to SAS...

%let stringvar=;
Data _null_;
  set work.test;
  if AddToStringYN = "Y" then do;
    call symput('stringvar',"" || strip(value));
  end;
Run;

...then SAS goes ahead and runs that code (which happens to be valid code, but is concatenating an empty string to the start of something). And because of the way the data step works, each iteration of the data step is in fact replacing the value of StringVar, which is why at the end of the data step, it's left with the last value that was read in.

苍暮颜 2024-11-11 02:14:18

问候
看起来很简单,这是我的解决方案:

data a;
set test end=eof;
length cat $100.;
retain cat;
if AddToStringYN = "Y" then do;
   cat=trim(left(cat))||trim(left(value));
end;
if eof then do;
   call symput("VAR",cat);
   output;
end;
run;

%put VAR=&VAR;

在这个示例中,您在“CAT”列的 A 数据集中有变量的串联,并且您有一个具有相同列表的宏变量 VAR

Greetings
Seems simple enough, here is my solution:

data a;
set test end=eof;
length cat $100.;
retain cat;
if AddToStringYN = "Y" then do;
   cat=trim(left(cat))||trim(left(value));
end;
if eof then do;
   call symput("VAR",cat);
   output;
end;
run;

%put VAR=&VAR;

in this example you have the concatenation of your variable in the A dataset in the column "CAT" and you have a macrovariable VAR with the same list

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文