P*****i 发帖数: 63 | 1 嗯,是哒,我就是在机器上跑过了还是不懂。
SAS运行结果如下:
199 options symbolgen;
200 %let a=begin;
201 %let b=%nrstr(&a);
202 %put UPCASE produces: %upcase(&b);
SYMBOLGEN: Macro variable B resolves to &a
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been
unquoted for printing.
SYMBOLGEN: Macro variable A resolves to begin
UPCASE produces: begin
~~~~~~~~~~~~~~~~~~~~~~~
这里为什么UPCASE不进一步执行替换大写的操作?
203 %put QUPCASE produces: %qupcase(&b);
SYMBOLGEN: Macro variable ... 阅读全帖 |
|
P*****i 发帖数: 63 | 2 看到这一块时感觉好烦呀,困惑有如当年刚见识指针的指针一般。
好吧,我能理解,每个处理普通字符的宏函数都有一个对应处理特殊字符的宏函数,有如%UPCASE之于%QUPCASE。后者的作用就是能无视&和%这两个特殊解析宏的字符。
但当书上这个例子一抛出,楼主便陷入了懵逼中。
%let a=begin;
%let b=%nrstr(&a);
%put UPCASE produces: %upcase(&b);
%put QUPCASE produces: %qupcase(&b);
嵌套的宏解析...
一点点来捋吧。首先,带%的func一定是跟宏相关,要能解析带&后面的字符串参数,将宏替换为相应的值,再以对应的普通函数处理。所以,%UPCASE 就是专门处理宏为参数的UPCASE函数。
在这个例子里,宏a对应的值解析为begin, 宏b的赋值因为无视&的存在,所以解析为&a。
那么,%UPCASE(&b)上来先对&b做解析,得到&a, 然后
下一步呢?
是函数表达式变成了UPCASE(&a), 还是UPCASE(begin)?
但无论是哪个分支,都不大像能得出结果小写的begin啊。
后面Q... 阅读全帖 |
|
i*********e 发帖数: 783 | 3 6 %let a=begin;
7 %let b=%nrstr(&a);
8
9%put UPCASE produces: %upcase(&b);
UPCASE produces: begin
10 %put QUPCASE produces: %qupcase(&b);
QUPCASE produces: &A
put UPCASE produces: %upcase(&b);
Why is the outcome not the following
UPCASE produces: BEGIN
Thanks! |
|
i*********e 发帖数: 783 | 4 6 %let a=begin;
7 %let b=%nrstr(&a);
8
9%put UPCASE produces: %upcase(&b);
UPCASE produces: begin
10 %put QUPCASE produces: %qupcase(&b);
QUPCASE produces: &A
put UPCASE produces: %upcase(&b);
Why is the outcome not the following
UPCASE produces: BEGIN
Thanks! |
|
P*****i 发帖数: 63 | 5 今天又想了下,结果取决于函数执行的时序。
一步步细分来看:
%let b=%nrstr(&a);
对于%upcase(&b)的执行时序:
1. 因为&b含有macro trigger,所以先解析到&a
2. 这里谁先谁后很重要,在input stack里接下来一步如果是%upcase接管,
那么%upcase执行后结果变成了&A
3. 下一步,因为upcase已经执行过了,针对&A, word scanner不会再重复执行一遍转换大写的操作,结果只由macro trigger再行解析到begin, 这时候解析&a和&A没区别,都指向begin.
这样解释的关键是在时序上要按照先解析第一步, 然后马上执行upcase操作,之后再解析upcase执行完之后的结果三步来才说的通.
换成QUPCASE执行.
在第二步里同样是换成了&A, 但是因为mask掉了&,结果停留在&A不再做进一步解析.
同样道理来看:
%let a=one;
%let b=two;
%let c=%nrstr(&a &b);
310 The %INDEX Function Chapter 9
%put C: &c
%... 阅读全帖 |
|
k*******a 发帖数: 772 | 6 试试这个macro, 他把你所有数值型变量转化为对应的format,如果这个obs有至少一个'NA',
那么就设
置flag=1,否者flag=0
%macro flag(lib=, data=, out=);
proc sql;
select name, format, count(*) into
:var separated by ' ', :fmt separated by ' ', :n
from sashelp.vcolumn
where upcase(libname)=upcase("&lib") and
upcase(memname)=upcase("&data") and
type='num' and
format ne '';
quit;
data &out;
set &lib..&data;
flag=0;
%do i=1 %to &n;
if put(%scan(&var,&i), %scan(&fmt, &i, "' '")) = 'NA'
... 阅读全帖 |
|
k*******a 发帖数: 772 | 7 写了隔macro你试试看
%macro rename(lib=,data=);
proc sql;
select strip(name)||'='||compress(name,'_') into :rename separated by ' '
from sashelp.vcolumn
where upcase(libname)=upcase("&lib") and upcase(memname)=upcase("&data");
quit;
data new;
set &lib..&data;
rename &rename;
run;
%mend; |
|
l******m 发帖数: 111 | 8 PROC SQL;
CREATE TABLE TEST AS
SELECT *
FROM YOURDATA
WHERE UPCASE(COMPNAME) LIKE '%preferred%' OR UPCASE(COMPNAME) LIKE '%UNIT%'
OR UPCASE(COMPNAME) LIKE '%WARRANT%' OR UPCASE(COMPNAME) LIKE '%REIT%'
;
QUIT; |
|
u*****o 发帖数: 1224 | 9 Given data set SASHELP.CLASS:
NAME AGE
Mary 15
Philip 16
Robert 12
Ronald 15
The following submitted: %let value = philip;proc print data=sashelp.class;
run;
Which WHERE statement successfully completes the program and produces a
report?
D: where upcase(name)="%upcase(&value)";
upcase(&value)不是得到PHILIP 么,难道不是应该只把P大写? |
|
L*******d 发帖数: 38 | 10 The answer is D: where upcase(name)="%upcase(&value)";
Why?
The values in the dataset are not all upcase? |
|
A*******s 发帖数: 3942 | 11 %macro add_prefix(lib=, table=, prefix=);
proc sql noprint;
select cats(name, '=', substr(cats(upcase("&prefix"), "_", name), 1, 32)
) into: rename_list separated by " "
from dictionary.columns
where libname=upcase("&lib") and memname=upcase("&table")
;
quit;
data &lib..prfx_&table;
set &lib..&table;
rename &rename_list ;
run;
%mend; |
|
m****r 发帖数: 202 | 12 %macro add_suffix(lib=, table=, suffix=);
proc sql noprint;
select cats(name, '=',name, "_", substr(cats(upcase("&suffix")), 1, 32)
) into: rename_list separated by " "
from dictionary.columns
where libname=upcase("&lib") and memname=upcase("&table")
;
quit;
data &lib..prfx_&table;
set &lib..&table;
rename &rename_list ;
run;
%mend;
It gives me what I expect. Thanks all. |
|
k*******a 发帖数: 772 | 13 %put UPCASE produces: %upcase(%upcase(&b)); |
|
s******r 发帖数: 1524 | 14 sorry. There is a typo. I put SEPARATED as separate.
proc sql;
select distinct compress(name||'='||name||'_v') into :M_Var_list SEPARATED
by ' ' from
dictionary.columns
where libname=upcase('WORK') and memname=upcase('faminc');run;quit;
proc datasets lib=work;modify test;rename &M_Var_list;run;quit; |
|
R******d 发帖数: 1436 | 15 这个宏凑合看看吧
%macro pgxofy(filein=,flag=(Page x of y),append=N,outfile=,ls=132)/des='Page
x of y';
*以&flag为标识算总页数;
data _null_;
retain pg 0;
infile "&filein" end=last;
input;
if index(upcase(_infile_),"&flag") then do;
pg=pg+1;
end;
if last then call symput("totpg",put(pg,4.0));
run;
*将&flag标识替换为“page X of Y”;
data tttttttt;*(keep=text);
length text2 text $200.;
retain pg 0;
infile "&filein";
input;
if index(upcase(_infile_),"&flag") the |
|
l***a 发帖数: 12410 | 16 I assume you already store the text as a variable x in a data set a.
data a;
set a;
y=index('MASTERS',upcase(x));
z=substr(a, y-20, y+27);
w=index('STATISTICS',upcase(z));
if w>0 then master_stat=1;
drop y z w;
run;
, |
|
j*****7 发帖数: 4348 | 17 我的这段小code(把目录下所有的log文件集中起来), 在 Windows下运行没问题, 在
UNIX下就不行了。
filename getdir pipe "dir/b &dirname.*.log";
* Determine total number of LOG files to be processed;
data dirlist;
infile getdir length=len;
length fname $200;
input @;
input @1 fname $varying200. len;
fname=upcase(fname);
if substr(upcase(fname),1,1) in (&fprefix);
run;
是不是这个dir/b 在UNIX下不好使啊?
谢谢了。 |
|
o****o 发帖数: 8077 | 18 then wrap it into a macro:
%macro switch(type);
%global s1 s2;
%if %upcase(&type) eq HTML %then %do;
%let s1=html;
%let s2=xls;
%end;
%else %if %upcase(&type) eq PDF %then %do;
%let s1=pdf;
%let s2=pdf;
%end;
%mend;
%switch(pdf);
ods listing close;
ods &s1 file="&add.\table.&s2";
options orientation=landscape nodate
nonumber missing=" " papersize="letter";
ods &s1 close;
ods listing; |
|
D******n 发帖数: 2836 | 19 create a .vim directory under you home directory(there is a dot before
vim)
and then create a syntax directory under it
and then create a sas.vim file under the syntax directory
==============sas.vim======================
if version < 600
syntax clear
elseif exists("b:current_syntax")
finish
endif
syn case ignore
syn region sasString start=+"+ skip=+\\|\"+ end=+"+
syn region sasString start=+'+ skip=+\\|\"+ end=+'+
" Want region from 'cards;' to ';' to be captured (Bob Heckel)
sy... 阅读全帖 |
|
b****u 发帖数: 67 | 20 1. 请问b为啥不对呀 ?? 谢谢
%macro printdsn(dsn,vars);
%if &vars= %then %do;
proc print data=&dsn;
title "Full Listing of %upcase(&dsn) data set";
run;
%end;
%else %do;
proc print data=&dsn;
var &vars;
title "Listing of %upcase(&dsn) data set";
run;
%end;
%mend;
a. %printdsn(sasuser.courses, course_title days);
b. %printdsn(dsn=sasuser.courses, vars=course_title days)
c. %printdsn(sasuser.courses, course_title days)
d. %printdsn(sasuser.courses, cours... 阅读全帖 |
|
p***r 发帖数: 920 | 21 purpose: 想要做一个macro 循环调用 display, 输出不同的 survey answer as text,
然 后再根据其内容,人工的输入yes/no,以便于以后的数据分析。
problem: 整个 macro 可以运行,唯一的问题是,display 的 window 在循环调用的时
候不能正确的显示 survey answer. (我是将所有的 survey answer 输出到一连串
macro variable 里面去)。
Any solution or suggestion in proving the code is appreciated
code is here
################################
data surveydata;
input x $40.;
cards;
This is programe is useless
I dont think so
Maybe its usefull
Not very much
;run;
%macro survey;
data _null_;
set surveydat... 阅读全帖 |
|
j******o 发帖数: 127 | 22 Please try and to see if the three groups of id are what you want.
proc sort data=have out=have1 nodupkey; by id typle; run;
data _equ _sup _both;
set have1;
by id typle;
if first.id=last.id and upcase(trim(typle))='EQUIPMENT' then output
_equ(keep=id);
else if first.id=last.id and upcase(trim(typle))='SUPPLY' then output
_sup(keep=id);
else output _both(keep=id);
run; |
|
o******m 发帖数: 23 | 23 Following is an abbr I wrote to handle daily output needs, you can have a
look and learn learn.
-----------
DM LOG 'CLEAR'; DM OUTPUT 'CLEAR';
%MACRO SWITCH(TYPE);
%GLOBAL K1 K2;
%IF %UPCASE(&TYPE) EQ HTML %THEN %DO;%LET K1=; %LET K2=%STR(*);%END;
%ELSE %IF %UPCASE(&TYPE) EQ PDF %THEN %DO;%LET K1=%STR(*); %LET K2=;%END;
%MEND;
%SWITCH(HTML|PDF);
%LET TABLENAME=TABLE_TEMP;ODS _ALL_ CLOSE;
&K1. ODS HTML FILE="&ADD.\&TABLENAME.(&RUNDATE).XLS"; &K1. OPTION LINESIZE
=128 PAGESIZE=160;
&K2. ... 阅读全帖 |
|
t**s 发帖数: 156 | 24 如果知道有多少variable需要转换,也可以用下面的方法.
假定有100个variable
Data test1;
Set test;
Array allchar(*) _char_;
Array newvar(*) newvar1 - newvar100;
Do i=1 to dim(allchar);
newvar(i)=Input(allchar(i), best.);
End;
Run;
如果不知道, 先找出来
proc sql noprint;
select count(*) into:cnt from sashelp.vcolumn
where libname="WORK" and upcase(memname)="TEST" and upcase(type=)"CHAR";
quit;
Data test1;
Set test;
Array allchar(*) _char_;
Array newvar(*) newvar1 - newvar&cnt;
... 阅读全帖 |
|
s******8 发帖数: 102 | 25 我觉得应Format比较好。先定义一个Format,暂称之为statefmt, 里面每个州对应一个
不同的数字。
proc format;
value statefmt
alabama='1'
alaska='2'
...
vermont='50';
run;
data two;
set yourdata;
new_var=put(lowcase(state),statefmt.);
run;
或者用macro对每个不同的state值定义一个代码:
%macro s;
proc sql;
select distinct strip(upcase(state)) into: allstates separated by '|'
from yourdata;
%let ns=&sqlobs;
quit;
data two;
set yourdata;
select(strip(upcase(state));
%do i=1 %to &ns;
%let s=%scan(&allstates,&i,'|');
when("&s") new_var=&i;
%end;
otherwise;
en... 阅读全帖 |
|
u****d 发帖数: 23938 | 26 我昨天貌似也碰到类似情况,分被算到对手头上,他们还一个劲儿地说我记错了。
00,我觉得我们可能被老邢加黑名单了;否则以你我的智慧,中等偏上的水平,和大局
观,不至于是大赤脚。他的程序里肯定有个判断语句:
if upcase(substr(player_id, length(player_id)-3))="LOAD" then ........
了, |
|
w*z 发帖数: 71 | 27 to input character variables with same prefix, one cannot use
data text;
input n1-n10 $;
datalinse;
smithers michaels gonzalez hurth frank bleigh
rounder joseph peters sam
;
run;
but you can use array do define them first:
data text;
array names{*} $ n1-n10;
array capitals{*} $ c1-c10;
input names{*};
do i=1 to 10;
capitals{i}=upcase(names{i});
end;
datalines;
smithers michaels gonzalez hurth frank bleigh
rounder joseph peters sam
;
run; |
|
w***z 发帖数: 28 | 28 proc sql;
create table new as
select lastname, firstname
from test
where upcase(firstname) like 'N%';
quit; |
|
w***z 发帖数: 28 | 29 sorry.
using index is a good idea, Scimitar's code should work.
proc sql;
select names
from test1
where scan(upcase(names),2,',') like 'N%';
quit; |
|
s******r 发帖数: 1524 | 30 In this case, compress would be necessary to handle space.
proc sql;
select names
from test1
where compress(scan(upcase(names),2,',')) like 'N%';
quit; |
|
p********a 发帖数: 5352 | 31 data banana1;
run;
proc sql;
select memname from dictionary.members
where libname='WORK' and find(upcase(memname),'BANANA');
quit; |
|
o****o 发帖数: 8077 | 32 data one;
input id x y Z A B C;
datalines;
1 1 0 1 1 1 1
2 0 1 1 1 1 1
3 1 1 1 1 1 1
4 0 0 1 1 1 1
5 1 0 0 0 0 0
;
run;
proc contents data=one out=onevars(keep=name varnum where=(upcase(name)^='
ID')) noprint; run;
data _null_;
set onevars end=eof;
if _n_=1 then call execute('proc freq data=one noprint;');
call execute('table '||name||' /out'||compress('=_'||name)||'(where=('|
|name||'=1));');
if eof then call execute ('run;');
run;
options source ;
data _null_;
c |
|
a***e 发帖数: 102 | 33 Maybe you can try this:
if indexc(upcase(descriptions), "APPLE", "ORANGE", "GRAPE")>0 THEN fruit_
dummy=1;else fruit_dummy=0; |
|
R*********i 发帖数: 7643 | 34 Did lz say "space+CO" at the end?
In case there are "space+CO" in the middle of the string, try
if substr(reverse(upcase(a)),1,3)='OC ' then a=substr(a,1,length(a)-4); |
|
o****o 发帖数: 8077 | 35 libname y "c:";
%let path=%sysfunc(pathname(y));
filename getfiles pipe "dir/b /on &path.mas_*.sas";
data filenams;
infile getfiles length=l end=eof;
length filename $200;
input @;
input @1 filename $varying200. l;
filename=upcase(filename);
if eof then put filename=;
run; |
|
p********a 发帖数: 5352 | 36 Assume you are using Windows system. Here is an example
%let dir=c:\test;
libname dict "&dir.";
%sysexec cd &dir; %sysexec dir * /b/o:n >flist;
data indexfile;
length filen $200 ;
infile "&dir./flist" length=reclen;
input filen $varying256. reclen;
run;
data indexfile;
set indexfile;
length type $5;
dataname=upcase(scan(filen,1,'.'));
if find(dataname,'RXCLAIMS') then type='RX';
if find(dataname,'MEDCLAIMS') then type='MED';
if find(dataname,'DM_MEMBER') then type='MBR';
if find(dataname,'ENROL... 阅读全帖 |
|
l***a 发帖数: 12410 | 37 我以前弄过一个类似的步骤,code改一下帖这里,后面主要是import你可能用不到
options noxsync noxwait noxmin;
x "dir /b /s yourpath\import.csv";
options mprint mlogic;
%macro import(file, name);
data _&name.;
infile "&file";
run;
proc append base=total data=_&name. force;
run;
%mend import;
proc datasets lib=work;
delete total;
run;
data import;
infile 'yourpath\import.csv' truncover;
input file $100.;
length=index(upcase(reverse(scan(reverse(file),1,'\'))),'.TXT');
length name $20.;
if length>0 then do;
name=substr(revers... 阅读全帖 |
|
l*********s 发帖数: 5409 | 38 I am having some very weird bug while trying to write a macro that can
expend the short hand notion like var1--var11 used in SAS.
The "shorthand" macro works fine on its own, but fails to work when called
by the "formula" macro. The error message seems to say that "the set
statement in the data step is not valid or not in proper order", what's
going on?
Many thanks!
////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////... 阅读全帖 |
|
d******9 发帖数: 404 | 39 Use dictionary or SAS Help dataset, for example:
proc sql;
create table Z as
select *
from sashelp.vmember
where upcase(libname)='WORK';
quit; |
|
d******9 发帖数: 404 | 40 Or use macro to do it. Below codes works well, tested with few sample
datasets.
options mprint symbolgen;
data A_201201;
A=225;
run;
data A_201207;
A=226;
run;
data A_201205;
A=338;
run;
data R_201207;
A=338;
run;
data B_201279;
A=551;
run;
proc sql;
select memname into : tables separated by ' '
from sashelp.vtable
where libname='WORK' and upcase(substr(memname, 1,1))='A';
quit;
data combine;
set &tables;
run;
=============================
LOG:
45 data combine;
SYMBOLGEN: Macro ... 阅读全帖 |
|
j******o 发帖数: 127 | 41 昨天刚写了几段code,不过是对csv的,请你改一下用在Excel文件上吧。中间有些地方
可能不太完善(比如文件名不能有空格等),欢迎改进及简化。
----------------------------------------------------------------
libname backup "C:\Documents and Settings\Ying\Desktop\Test";
filename blah pipe 'dir "C:\Documents and Settings\Ying\Desktop\Test\*.csv"
';
data dirlist;
infile blah truncover lrecl=200;
input line $200. ;
if upcase(substr(line, 1, 9))='DIRECTORY' then call symput('direc', trim
(substr(line, 14, length(line))));
if input(substr(line,1,10), ??... 阅读全帖 |
|
s******r 发帖数: 1524 | 42 大包子 pls.
%macro test;
proc sql;
create table var_ls as select distinct name from dictionary.columns
where libname='WORK' and memname='TEST' and upcase(name) ne 'ID';quit;run;
data _null_;set var_ls;
call symput(cats('var',_n_),name);
call symput('cnt',_n_);
run;
proc sql;
create table test2 as
select id
%do i = 1 %to &cnt;
,max(&&var&i) as &&var&i
%end;
from test
group by id;quit;run;
%mend;
%test;
but |
|
k*******a 发帖数: 772 | 43 可以用 SAS 的dictionary来找出data有什么variable
data test;
input var1 $ var2 $;
datalines;
3.4 5
4.55 5.3
4 3.444
;
run;
proc sql noprint;
select strip(name)||"_n=input("||strip(name)||",best12.)" into :convert
separated by ";"
from sashelp.vcolumn
where libname="WORK" and upcase(memname)="TEST";
quit;
data test1;
set test;
&convert;
run; |
|
j*********g 发帖数: 44 | 44 Create a macro that runs an analysis of variance model with two factors,
where there may or may not be an interaction in the model. The macro should
allow for the residuals to be obtained in an output data. The call for the
macro must allow for the name of the input data set, the response variable,
the explanatory variables, the name of the output data set, and whether or
not there is an interaction in the model. Here's the challenge: whether
there is an interaction in the model might be s... 阅读全帖 |
|
b*****y 发帖数: 175 | 45 简历要准确 会什么就写什么 写上去的就应该是会了的 掌握了的
刚毕业的学生 一定要写上课程 课上学的基本概念要清楚, 而且只要求最基本的概念。
SAS最重要。但是也只要求最基本的知识。比如proc import, proc sort, set, merge,
proc transpose, proc freq, proc univerte, some functions such as put, input
, substr, upcase, strip.
以上只针对中小型CRO, 各种高大上公司不在本帖讨论范围。 |
|
P*****i 发帖数: 63 | 46 恭喜楼主,进度马上就要赶超我了。我现在卡在macro章节里看得很痛苦。
坐等楼主开解macro问题,比如书上举的%UPCASE那个输出仍为小写begin的,还有像%SUBSTR那个我在自己机器上连跑都跑不起来直接报错,说有recursive调用。 |
|