I may be missing something obvious, but how do you calculate 'powers' in SAS?
Eg X squared, or Y cubed?
what I need is to have variable1 ^ variable2, but cannot find the syntax... (I am using SAS 9.1.3)
got it! there is no function.
you need to do:
variable1 ** variable2;
data t;
num = 5;
pow = 2;
res = num**pow;
run;
proc print data = t;
run;
Use the POWER function and, if necessary, the CONSTANT function.
nbr_squared = power(nbr, 2);
nbr_cubed = power(nbr, 3);
E_to_the_power_2 = power(constant('E'),2);
Related
I created a SAS function using fcmp to calculate the jaccard distance between two strings. I do not want to use macros, as I'm going to use it through a large dataset for multiples variables. the substrings I have are missing others.
proc fcmp outlib=work.functions.func;
function distance_jaccard(string1 $, string2 $);
n = length(string1);
m = length(string2);
ngrams1 = "";
do i = 1 to (n-1);
ngrams1 = cats(ngrams1, substr(string1, i, 2) || '*');
end;
/*ngrams1= ngrams1||'*';*/
put ngrams1=;
ngrams2 = "";
do j = 1 to (m-1);
ngrams2 = cats(ngrams2, substr(string2, j, 2) || '*');
end;
endsub;
options cmplib=(work.functions);
data test;
string1 = "joubrel";
string2 = "farjoubrel";
jaccard_distance = distance_jaccard(string1, string2);
run;
I expected ngrams1 and ngrams2 to contain all the substrings of length 2 instead I got this
ngrams1=jo*ou*ub
ngrams2=fa*ar*rj
If you want real help with your algorithm you need to explain in words what you want to do.
I suspect your problem is that you never defined how long you new character variables NGRAM1 and NGRAM2 should be. From the output you show it appears that FCMP defaulted them to length $8.
To define a variable you need use a LENGTH statement (or an ATTRIB statement with the LENGTH= option) before you start referencing the variable.
I got the following error:
I don't understand my error please help.
you need space between do and _i_ (index variable) as shown below. as you have it as do_i_. your warning also gives a clue about this.
data RV2;
retain _seed_ 0;
n=20;
p=0.6;
do _i_ = 1 to 100;
binorm1= ranbin(_seed_,n, p);
output;
end;
drop _seed_ _i_;
run;
Essentially, what I would like to do is use the min/max function while altering a table. I am altering a table, adding a column, and then having that column set to a combination of a min/max function. In SAS, however, you can't use summary functions. Is there a way to go around this?
There are many more inputs but for the sake of clarity, a condensed version is below! Thanks!
%let variable = 42
alter table X add Z float;
update X
set C = min(max(0,500 - %sysevalf(variable)),0);
First, let's remove the %sysevalf(), they are not needed and format for readability
alter table claims.simulation add Paid_Claims_NoISL float;
update claims.simulation
set Paid_Claims_NoISL
= min(
max(0
, Allowed_Claims -&OOPM
, min(Allowed_Claims
,&Min_Paid+ max(Allowed_Claims - &Deductible * &COINS
,0
)
)
, &Ind_Cap_Claim
)
);
Notice that the first min() only has 1 argument. That is causing your ERROR. SAS thinks that because it only has 1 input, you want to summarize a column, which is not allowed in an update.
Just take that out and it should work:
alter table claims.simulation add Paid_Claims_NoISL float;
update claims.simulation
set Paid_Claims_NoISL
= max(0
, Allowed_Claims -&OOPM
, min(Allowed_Claims
,&Min_Paid+ max(Allowed_Claims - &Deductible * &COINS
,0
)
)
, &Ind_Cap_Claim
);
To reference the value of a macro variable you need to use &.
%let mvar = 42;
proc sql;
update X set C = min(max(0,500 - &mvar),0);
quit;
Note there is no need to use the macro function %SYSEVALF() since SAS can more easily handle the case when the value &mvar is an expression than the macro processor can.
%let mvar = 500 - 42;
proc sql;
update X set C = min(max(0,&mvar),0);
quit;
I'm trying to compare if a number of different variables happen in the order I expect using a macro. My code is:
%macro Order (second,first,var);
data order;
set data;
if &second. > &first. then &var._Correct = 1; else &var._Correct = 0;
if &second. < &first. then &var._Error = 1; else &var._Error = 0;
run;
%mend order;
%order(B,A,AB);
%order(C,B,BC);
I have a lot of other variables to compare. The problem is, when I run the macro the output dataset only has the last pair. In this example, that would be BC. I know I can make multiple output datasets and each one would have the pairs, but then I'd have to rejoin them all together. How can I get one dataset that has all of my &var._Correct and &var._Error pairs?
Your problem is that you're rewriting the data step twice. That's unneeded. Most of the time, macros like this can be lines in a data step not whole data steps.
%macro Order (second,first,var);
if &second. > &first. then &var._Correct = 1; else &var._Correct = 0;
if &second. < &first. then &var._Error = 1; else &var._Error = 0;
%mend order;
data order;
set data;
%order(B,A,AB);
%order(C,B,BC);
run;
Something more like that. I'd note a few minor issues here. What if &second=&first? You want no correct and no error, or is that correct or error?
And an easier way to do this:
%macro Order (second,first,var);
&var._correct = (&second. > &first.); *or GE?;
&var._error = (&second. < &first.); *or LE?; *only one of these two;
%mend order;
That puts the same values into the variable in a lot less code.
I'm trying to create a code to run a simple perceptron in SAS base.
I'd like to print in each iteration (or store in a table) the result and the target, but I get an error when I try to print y[i,]:
proc iml;
use percept; read all var{x1 X2} into X;
read all var{Y} into Y;
W={0,0}; b=0; k=0; L=nrow(X); eta=.8; o=0;
print w b k L eta;
do step = 1 to 6;
mistakes=0;
do i=1 to L;
o=(X[i, ]*W + b);
if Y[i, ]*o <= 0 then do;
W = W + eta*(Y[i, ]-o)*X[i,]`;
b = b + eta*(Y[i, ]-o)*1;
k=k+1; mistakes=mistakes+1;
print o Y[i, ] W b k mistakes;
end;
end;
end;
I get the error:
Syntax error, expecting one of the following: C, COLNAME, F, FORMAT,
L, LABEL, R,
ROWNAME, ], |). The option or parameter is not recognized and will be ignored.
Do I have any other form to print the target?
Thanks a lot!
Per the documentation on PRINT, you need to do it like this:
print(Y[i,])
This is because they overload the [ ] to indicate formatting, rownames/colnames, etc., which is rather silly (but presumably to imitate some other language?). So you just need to wrap (Y[i,]) like so.
Here's a silly example.
proc iml;
use sashelp.class;
read all var{name,sex} into class;
read all var{height,weight,age} into classN;
y = mean(classN[,2]);
print class;
print (class[1:2,]);
print y (class[1:2,]);
quit;