Is possible to use method proc with parameters in Crystal ?
Something like:
def foo(baz)
puts "#{baz} foo!"
end
proc = ->foo
proc.call "Hi"
Yes. If the method has arguments, you must specify their types:
proc = ->foo(String)
proc.call "Hi" # Hi foo!
Find more examples at crystal docs.
Related
I want to tell SAS to capture specific observation under the variable "rashloc_spcy" (and others) for a string observations ("B", "P/G", "Peri", "Gen"). However, when I see the results, SAS is capturing other observations not described in my statement. Is there anything I can do to modify my code?
output result
proc print data=k.dataset;
var rashloc_GNT rashloc_PER rasloc_Spcfy;
where ((rashloc_GNT = "GNT") OR (rashloc_PER = "PER")) OR rashloc_Spcfy in ("B", "P/G", "Peri", "Gen"));
run;
I should be getting only the quoted keyterms in the variable of interest (rashloc_spcfy)
So you want to exclude cases where the third variable is some other non missing value if they meet the first two criteria?
So perhaps?
where ((rashloc_GNT = "GNT") OR (rashloc_PER = "PER"))
and not (rashloc_Spcfy not in (" ","B","P/G","Peri","Gen"))
;
I have a project with multiple programs. Each program has a proc SQL statement which will use the same list of values for a condition in the WHERE clause; however, the column type of one database table needed is a character type while the column type of the other is numeric.
So I have a list of "Client ID" values I'd like to put into a macro variable as these IDs can change, and I would like to change them once in the variable instead of in multiple programs.
For example, I have this macro variable set up like so and it works in the proc SQL which queries the character column:
%let CLNT_ID_STR = ('179966', '200829', '201104', '211828', '264138');
Proc SQL part:
...IN &CLNT_ID_STR.
I would like to create another macro variable, say CLNT_ID_NUM, which takes the first variable (CLNT_ID_STR) but removes the quotes.
Desired output: (179966, 200829, 201104, 211828, 264138)
Proc SQL part: ...IN &CLNT_ID_NUM.
I've tried using the sysfunc, dequote and translate functions but have not figured it out.
TRANSLATE doesn't seem to want to allow a null string as the replacement.
Below uses TRANSTRN, which has no problem translating single quote into null:
1 %let CLNT_ID_STR = ('179966', '200829', '201104', '211828', '264138');
2 %let want=%sysfunc(transtrn(&clnt_id_str,%str(%'),%str())) ;
3 %put &want ;
(179966, 200829, 201104, 211828, 264138)
It uses the macro quoting function %str() to mask the meaning of a single quote.
Three other ways to remove single quotes are COMPRESS, TRANSLATE and PRXCHANGE
%let CLNT_ID_STR = ('179966', '200829', '201104', '211828', '264138');
%let id_list_1 = %sysfunc(compress (&CLNT_ID_STR, %str(%')));
%let id_list_2 = %sysfunc(translate(&CLNT_ID_STR, %str( ), %str(%')));
%let id_list_3 = %sysfunc(prxchange(%str(s/%'//), -1, &CLNT_ID_STR));
%put &=id_list_1;
%put &=id_list_2;
%put &=id_list_3;
----- LOG -----
ID_LIST_1=(179966, 200829, 201104, 211828, 264138)
ID_LIST_2=( 179966 , 200829 , 201104 , 211828 , 264138 )
ID_LIST_3=(179966, 200829, 201104, 211828, 264138)
It really doesn't matter that TRANSLATE replaces the ' with a single blank () because the context for interpretation is numeric.
I am working with SAS and want to record variable which with over 50+ different qualitative dummies. For example, the state of the U.S.
In this case, I just want to reduce them into 4 or 5 levels dummy as quantitative variable.
I get several ideaS, for example to use if/else statement, however, the problem is that i have to write down and specify each of area name in SAS and the code looks like super heavy.
Is there any other ways to do that without redundant code? Or to avoid write each specific name of variable? In SAS.
Any ideas are appreciated!!
Method 1:
Use IN, but you still have to list the variables. You can also do it via a format, but you have to define the format first anyways.
if state in ('AL', 'AK', 'AZ' ... etc) then state_group = 1;
else if state in ( .... ) then state_group = 2;
Method 2:
For a format, you create format using PROC FORMAT and then apply it.
proc format;
value $ state_grp_fmt
'AL', 'AK', 'AZ' = 1
'DC', 'NC' = 2 ;
run;
And then you can use it with a PUT statement.
State_Group = put(state, state_grp_fmt);
I read the documentation on Procs in the Crystal Language book on the organizations’s site. What exactly is a proc? I get that you define argument and return types and use a call method to call the proc which makes me think it’s a function. But why use a proc? What is it for?
You cannot pass methods into other methods (but you can pass procs into methods), and methods cannot return other methods (but they can return procs).
Also Proc captures variables from the scope where it has been defined:
a = 1
b = 2
proc = ->{ a + b }
def foo(proc)
bar(proc)
end
def bar(proc)
a = 5
b = 6
1 + proc.call
end
puts bar(proc) # => 4
A powerful feature is to convert a block to Proc and pass it to a method, so you can forward it:
def int_to_int(&block : Int32 -> Int32)
block
end
proc = int_to_int { |x| x + 1 }
proc.call(1) #=> 2
Also, as #Johannes Müller commented, Proc can be used as a closure:
def minus(num)
->(n : Int32) { num - n }
end
minus_20 = minus(20)
minus_20.call(7) # => 13
The language reference explains Proc pretty well actually:
A Proc represents a function pointer with an optional context (the closure data).
So yes, a proc is essentially like a function. In contrast to a plain block, it essentially holds a reference to a block so it can be stored and passed around and also provides a closure.
A Proc is simply a function/method without a name. You can pass it around as a variable, and it can refer to variables in it's enclosing scope (it's a closure). They are often used as a way of passing method blocks around as variables.
so I have a dataset whose elements are strings of emails in quotes. A single data element might look like this:
"john#cool.com" "jacob#cool.com" "jingleheimer#cool.com" "smith#cool.com"
I have the following macro command and data step:
%macro Emailer(RCP=);
/* body of the e-mail*/
data _null_;
file tmp;
put "Hello, World! <BR>";
run;
/*to-from*/
Filename tmp Email
Subject="Hello World Test"
To= (&RCP)
CT= "text/html";
%mend Emailer;
data _null_;
set EmailLists;
call execute('%Emailer(RCP='||ListOfEmails||')');
run;
But I keep getting "ERROR: Macro parameter contains syntax error."
Is it because my data elements have spaces or quotation marks or both?
Thanks in advance.
One way to test it is to pass the parameters directly, rather than with a data step. First I'll rearrange the order of the statements, as commenters pointed out.
%macro Emailer(RCP=);
filename myEmail Email;
data _null_;
file myEmail Subject = "Hello World Test"
To = (&RCP)
CT = "text/html";
put "Hello, World! <BR>";
run;
filename myEmail clear;
%mend Emailer;
And try making any of those work (can't make my 64-bit SAS work with my 32-bits Outlook so I can't test any of this):
%Emailer(RCP="john#cool.com" "jacob#cool.com" "jingleheimer#cool.com")
%Emailer(RCP="john#cool.com jacob#cool.com jingleheimer#cool.com")
%Emailer(RCP=john#cool.com jacob#cool.com jingleheimer#cool.com)
%Emailer(RCP=john#cool.com ; jacob#cool.com ; jingleheimer#cool.com)
After you figure out which form works, the rest should be easy.