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;
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 am trying to concatenate three string variables.
Data X ;
a = "A" ;
b = "B" ;
c = "C" ;
z = catx ( '0D0A'x, a, b, c ) ;
run;
I am trying to display the string values like this in the final dataset, so that the values appear one below the other -
A
B
C
But by using '0D0A'x option, the string appears as ABC. I have to display the z variable in an excel. If I had to output the same into a HTML file then I would have used "\n" as an option in CATX function. Is there a way where I can introduce new line characters.
I adapted your example slightly:
libname test excel "%sysfunc(pathname(work))\text.xls";
Data test.X ;
a = "A" ;
b = "B" ;
c = "C" ;
z = catx ( '0D0A'x, a, b, c ) ;
run;
libname test clear;
x "explorer ""%sysfunc(pathname(work))\text.xls""";
If you use this approach, you get a value in cell D2 which contains the line breaks as expected. However, in order for them to display correctly, you have to enable the 'wrap text' option for the cell formatting.
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 have some SAS code along the lines of:
DATA MY_SAMPLE;
SET SAMPLE;
BY A;
IF A = 1 THEN B = 1;
ELSE IF A ^= 1 THEN B = 0;
ELSE IF MISSING(A) THEN B = .;
IF FIRST.A;
RUN;
which is returning a set with 0 observations (it shouldn't do this). I have sorted the data by A and tried reading the data into an intermediate dataset before applying the IF FIRST.A but get the same results.
Am I missing something completely obvious? I use the FIRST and LAST all of the time!
Agree with #Robert, the sample code should output records, assuming there are records in your input data and it is sorted.
I would double-check the log from your real program/data, and make sure there are no errors, and that the input dataset has records.
If that doesn't help, I would add some debugging PUT statements, something like below (untested):
DATA MY_SAMPLE;
SET SAMPLE;
BY A;
IF A = 1 THEN B = 1;
ELSE IF A ^= 1 THEN B = 0;
ELSE IF MISSING(A) THEN B = .; *This will never be true ;
put "Before subsetting if " (_n_ A first.A)(=) ;
IF FIRST.A;
put "After subsetting if " (_n_ A first.A)(=) ;
RUN;
As Robert noted, as written your Else if Missing(A) would never be true, because if A is missing the prior Else if A ^= 1 will evaluate to true because SAS uses binary logic (true/false), not trinary logic(true/false/null).
Also I would check for any stray OUTPUT statements in your code.
Checked the log; checked the input; closed MSSQL down; opened it up again and lo and behold, code worked first time. Thanks for the downgrade, but I didn't realize that MSSQL is prone to twitches!
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);