SAS new variable name using macro variable - sas

I am trying to create a new variable based on the value of a macro variable. However, SAS highlights 'vari' as red, seemingly indicating that I am doing something wrong. The statement still seems to get executed correctly though. Any thoughts?
%let i=7;
data d1;
set d1;
vari&i=7;
run;

SAS syntax highlighter is an aid, but there are many situations where it is not "correct". Particularly for the macro language, it can't always guess how symbols will resolve. It doesn't have all the information (or intelligence) as the SAS word scanner/tokenizer. I use syntax highlighting as a hint that something might be wrong, but I ignore it when I've checked the code and confirmed it is correct.
The code in your example is fine.

Related

SAS Apparent symbolic reference when there is a n ampersand in data

This appears to be an old problem but I haven't seen an answer that fully addresses it. Totally possible I just missed it.
I'm consuming data that has a text field called fullDescription that contains a string like (made up but fits the pattern):
"00001234456 Wells Fargo DR FM AT&T PYMT 00987600"
I'm attempting to parse the data and dig out tidbits like "Wells Fargo" and "AT&T". However, when I manipulate "AT&T" SAS tries to read it as "AT" then the variable value for T. It stopped erroring (but still warns) when I instituted this line:
%LET description = %SYSFUNC(COMPRESS(%BQUOTE(&&fullDescription&row),'',P));
This, at least, returns "00001234456 Wells Fargo DR FM ATT PYMT 00987600" (missing ampersand) but still throws:
WARNING: Apparent symbolic reference T not resolved
I haven't figured out a way to prevent the warning. Is there a way to leave the ampersand in but not treat it as a variable? If that's not possible, can I cleanse it once and not get the error?
You are almost there, just add %nrstr() function when define the macro variable fullDescription.
data _null_;
call symputx('fullDescription','%nrstr(00001234456 Wells Fargo DR FM AT&T PYMT 00987600)');
run;
%LET description = %SYSFUNC(COMPRESS(%bquote(&fullDescription),'',P));
%put &=description;
This makes no warning anymore.

Put with macro variable as format

I have a dataset with a variable called pt with observations 8.1,8.2,8.3 etc and a variable called mean with values like 8.24 8.1 8.234 etc. Which are paired with each other.
I want to be able to set my put informat to the formats from the variable num.
I get the errors "Expecting an arithmetic expression"
"the symbol is not recognized and will be ignored" and "syntax error" from my code. (underlining the &fmt. part)
if pt=&type;
call symput("fmt",pt);
fmt_mean = putn(mean,&fmt.);
Thanks in advance for your help.
The macro processor's work is done before SAS compiles and runs the data step. So trying to place the value into a macro variable and then use it immediately to generate and execute SAS code will not work.
But since you are using the PUTN() function it can use the value of an actual variable, so there is no need to put the format into a macro variable.
fmt_mean = putn(mean,pt);
Please, post your data set and data step. Your description is hard to understand.
However the solution seems to be simple: do not use macro variables! You don't need them here. Unlike put() function which expect format know at compile time (that is when you can use macro variables) its analog putn() expects second argument to be variable. Of course, it works a little slower due to that permittance. So your code can look like that:
data ...;
set ...(keep=mean pt);
fmt_mean = putn(mean, pt);
run;
where pt variable maybe numeric, i.e. 8.2, or character, i.e. '8.2'.
If you want to understand how SAS macro works and what call symput does look here:
https://stackoverflow.com/a/69979074/7864377

SAS Data integration studio

Long time reader first-time questioner.
Using SAS Data Integration studio, when you create a summary transformation in the table options advanced tab you can add a where statement to your code automatically. Unfortunately, it adds some code that makes this resolve incorrectly. Putting the following in the where text box:
TESTFIELD = "TESTVALUE"
creates
%let _INPUT_options = %nrquote(WHERE = %(TESTFIELD = %"TESTVALUE%"%));
In the code, used
proc tabulate data = &_INPUT (&_INPUT_options)
But resolves to
WHERE = (TESTFIELD = "TESTVALUE")
_
22
ERROR: Syntax error while parsing WHERE clause. ERROR 22-322: Syntax
error, expecting one of the following: a name, a quoted string, a
numeric constant, a datetime constant,
a missing value, (, *, +, -, :, INPUT, NOT, PUT, ^, ~.
My question is this: Is there a way to add a function to the where statement box that would allow this quotation mark to be properly added here?
Note that all functions get the preceding % when added to the where statement automatically and I have no control over that. This seems like something that should be relatively easy to fix but I haven't found a simple way yet.
The % are simply escaping the " and () characters; they're perfectly harmless, really. The bigger problem is the %NRQUOTE "quotes" (which are nonprinting characters that tell SAS this is macro-quoted); they mess up the WHERE processing.
Use %UNQUOTE( ... ) to remove these.
Example:
data have;
testfield="TESTVALUE";
output;
testfield="AMBASDF";
output;
run;
%let _INPUT_options = %nrquote(WHERE = %(TESTFIELD = %"TESTVALUE%"%));
%put &=_input_options;
data want;
set have(%unquote(&_INPUT_options.));
run;
Thank you all for your responses. Long story short, I ended up creating a SAS Troubleshooting ticket. The analyst told me that they have now documented the issue, which should now be resolved in a future iteration of DI.
The temporary solution was to create a new transformation, with a slight alteration, adding an UNQOUTE (as mentioned above by Joe) to the source code before the input options:
proc tabulate data = &_INPUT (%unquote(&_INPUT_options)) %unquote(&procOptions);
For those interested you will need to create the transformation in a public subfolder of your project so others can use it. Not what I was hoping for, but a workable solution while waiting for the version update.

Stata : generate/replace alternatives?

I use Stata since several years now, along with other languages like R.
Stata is great, but there is one thing that annoys me : the generate/replace behaviour, and especially the "... already defined" error.
It means that if we want to run a piece of code twice, if this piece of code contains the definition of a variable, this definition needs 2 lines :
capture drop foo
generate foo = ...
While it takes just one line in other languages such as R.
So is there another way to define variables that combines "generate" and "replace" in one command ?
I am unaware of any way to do this directly. Further, as #Roberto's comment implies, there are reasons simply issuing a generate command will not overwrite (see: replace) the contents of a variable.
To be able to do this while maintaining data integrity, you would need to issue two separate commands as your question points out (explicitly dropping the existing variable before generating the new one) - I see this as method in which Stata forces the user to be clear about his/her intentions.
It might be noted that Stata is not alone in this regard. SQL Server, for example, requires the user drop an existing table before creating a table with the same name (in the same database), does not allow multiple columns with the same name in a table, etc. and all for good reason.
However, if you are really set on being able to issue a one-liner in Stata to do what you desire, you could write a very simple program. The following should get you started:
program mkvar
version 13
syntax anything=exp [if] [in]
capture confirm variable `anything'
if !_rc {
drop `anything'
}
generate `anything' `exp' `if' `in'
end
You then would naturally save the program to mkvar.ado in a directory that Stata would find (i.e., C:\ado\personal\ on Windows. If you are unsure, type sysdir), and call it using:
mkvar newvar=expression [if] [in]
Now, I haven't tested the above code much so you may have to do a bit of de-bugging, but it has worked fine in the examples I've tried.
On a closing note, I'd advise you to exercise caution when doing this - certainly you will want to be vigilant with regard to altering your data, retain a copy of your raw data while a do file manipulates the data in memory, etc.

How to clear session of open error

When working is the base sas client, if a user accidentially forgets a parathesis, quote, semi-colon, or end-comment that will sometimes cause any additional code they try running to fail. If I'm trying to help someone experiencing one of these errors, how can I clear the current buffer and start fresh without opening a brand new session?
I've always used the one documented on support.sas.com
http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a001302436.htm
*'; *"; *); */; %mend; run;
Submit that until you get the log message :
ERROR: No matching %MACRO statement for this %MEND statement.
There is no true best way, as it depends on too many things. Presumably the user will know what might have gone wrong, and can use that information; for example, are we possibly missing a %mend somewhere that caused us to get locked into a macro?
The EG method is one of the better ones. At the start of every EG process (ie, every time you hit 'Run' on a program or section of program), it runs:
;*';*";*/;quit;run;
That:
Semicolon ends any statement that hadn't ended
Comment singlequote, and comment doublequote, end any trailing quotes (both trailed by ; )
Star slash ends any block comments
Quit and run end any procedures that had been left open.
EG doesn't include %mend; because it would generate a warning, but you could include that if you didn't mind the warning and wanted to catch one of the common issues. If you do include it, put it up front - macros will not properly deal with those hanging quotes, and you need to be out of them for sure first.