/******************************* TOSA_V **********************************/ /****This program is used to calculate vector based topological change****/ /***********************Author: Nan "Wendy" Li ***************************/ /***********************wendyli0611@gmail.com*****************************/ /****************************May 16, 2015*********************************/ proc printto log="C:\temp\Save_my_log_please.log" new; /***Creat a log file***/ %macro TOSA_V(sample,data); /*Input data*/ data _null_; call symputx('ndat',count("&data",'|')+1); run; %do k=1 %to &ndat; /*Read data from an Excel spreadsheet*/ %let dat=%scan(&data,&k,'|'); data vector_&dat; set _null_; run; proc import out = &dat datafile = "&path.\&sample..xls" dbms = xls REPLACE; sheet = "&dat"; getnames = yes; run; proc contents data=&dat out=content;run; /*Read raw data into a SAS data table*/ proc sort data=content; by VARNUM;run; proc sql; select name into: vlist separated by ' ' from content; select count(name) into: nv from content; select distinct(NOBS) into: num from content; run; quit; %let num=%trim(%left(&num)); /*Initialize parameters*/ proc corr data=&dat cov out=cov; /*Calculate covirance matrix*/ var &vlist; run; data cov; set cov; /*Save covirance matrix*/ keep &vlist; if _n_ in (1:&nv); run; proc iml; /*Calculate the inverse matrix of original covirance matrix*/ use cov; read all into cov; close cov; cov_inv=inv(cov); use &dat; read all into g; close &dat; %do i=1 %to # /*Calculate the angle between any two vectors*/ %let t=&i+1; %do j=&t %to # c1=g[&i,]; c2=g[&j,]; t_c1=t(c1); t_c2=t(c2); _tmp=c1*cov_inv*t_c2; _r1=c1*cov_inv*t_c1; _r2=sqrt(_r1); _q1=c2*cov_inv*t_c2; _q2=sqrt(_q1); _rq=_r2*_q2; _rq_inv=inv(_rq); _z&i&j=_tmp*_rq_inv; create _z&i&j from _z&i&j[colname={"vector_&dat"}]; append from _z&i&j; %end; %end; quit; %do i=1 %to # /*Calculate the results*/ %let t=&i+1; %do j=&t %to # data vector_&dat; set vector_&dat _z&i&j;run; %end; %end; proc datasets nolist; delete _z:; run; quit; %end; data test; merge vector_input vector_output; /*Calculate the suqare sum of the angle difference between input and output data*/ diff_sq=(vector_output-vector_input)**2; run; proc means data=test; var vector_output vector_input diff_sq; output out=means(drop=_TYPE_ _FREQ_); run; data means; set means; /*Calculate the mean difference*/ if _STAT_ in ('MEAN' 'N'); if _STAT_='N' then _STAT_='num_of_s'; if _STAT_='MEAN' then diff=sqrt(diff_sq); /*Calculate the result*/ run; proc export data= work.means /*Export the results*/ outfile= "&path.\TOSAV_result.xls" dbms=excel replace; sheet="TOSAV_result"; run; %mend; %TOSA_V(sample=sample, data=input|output, path=C:\test); proc printto; title; run;