SAS程序,如何在没有IML的情况下基于两个表进行计算

SAS程序,如何在没有IML的情况下基于两个表进行计算,sas,sas-macro,Sas,Sas Macro,我一直在为sas中的一些矩阵计算而挣扎。 我有两个表,都包含经度和纬度信息 任务表 工程师表: 我的输出目标是任务和工程师之间的距离 距离: 由于SAS/IML的额外成本,我没有在本地安装。有没有人有这样做的经验 另外,R中的代码很简单,如下所示 distances <- matrix(nrow = NROW(tasks), ncol = NROW(cses)) for (i in 1:NROW(tasks)){ for(j in 1:NROW(cses)){

我一直在为sas中的一些矩阵计算而挣扎。 我有两个表,都包含经度和纬度信息

任务表

工程师表:

我的输出目标是任务和工程师之间的距离

距离:

由于SAS/IML的额外成本,我没有在本地安装。有没有人有这样做的经验

另外,R中的代码很简单,如下所示

   distances <- matrix(nrow = NROW(tasks), ncol = NROW(cses))
   for (i in 1:NROW(tasks)){
     for(j in 1:NROW(cses)){
       distances[i,j] <- distm (c(tasks$CUST_LNG_X[i], tasks$CUST_LAT_Y[i]), c(cses$LNG_X[j], cses$LAT_Y[j]), fun = distHaversine)

     }
   }
距离有一个函数就是这样做的

假设名为
tasks
engineers
的表格具有您在文章中提供的结构(供将来参考,我们将其作为文本而不是图像),您可以获得具有以下内容的第三个表格:

proc sql;
create table engineers_2 as
select compress(id||'_y') as id
      ,geo_y as geo
from engineers
union
select compress(id||'_x') as id
      ,geo_x as geo
from engineers
order by id
;
quit;

proc transpose data=engineers_2 out=t_engineers(drop=_name_);
var geo;
id id;
run;

proc sql;
create table want as
select *
from tasks
    ,t_engineers
;
quit;
这将为您提供一个包含以下列的表

task_id geo_y geo_x E_1_x E_1_y E_2_x E_2_y E_3_x E_3_y
其中
geo_y
geo_x
是任务的坐标
task_id
E_n_x
E_n_y
是工程师的坐标
n


然后,只需逐行处理数据集,在
geodist
函数中输入变量。

这与user2877959非常相似

data tasks;
input Task_ID $ Y X;
datalines;
T_1 41.65 -74.08
T_2 32.48 -86.46
;
run;

%let n=2; /*This is the number of engineer points*/

data engineers;
input ID $ Y X;
datalines;
E_1 40.92 -81.31
E_2 39.98 -74.87
;
run;
我的不同之处在于,创建
X_
Y_
都是后缀。这将使事情变得更容易。我在一个数据步骤中这样做,然后转置。使用SQL也很有效

data engineers;
set engineers;
X_NAME = catt("X_",id);
Y_NAME = catt("Y_",id);
run;

proc transpose data=engineers(keep=x_name x) out=e_x;
id x_name;
run;

proc transpose data=engineers(keep=y_name y) out=e_y;
id y_name;
run;

/*This puts the engineer data into 1 record in a single table*/
data engineers;
merge e_y e_x;
drop _name_;
run;

proc sql noprint;
create table want as
select a.*,
       b.*
    from tasks a,
         engineers b;
quit;
最后一步是计算距离。我们可以使用数据步数组来帮助处理

data want;
set want;
array E_[&n];
array X_E_[&n];
array Y_E_[&n];

do i=1 to &n;
    E_[i] = geodist(x,y,x_e_[i],y_e_[i]);
end;

drop X: Y: i;
run;

也许我遗漏了一些东西,但是交叉连接也应该可以很好地使用GEODIST函数,然后使用转置使其变宽。每个文件中有多少个点并不重要,尽管我认为如果文件足够大,SQL可能会由于内存而出错

proc sql;
create table want as
select task_id as col1, id as col2, geodist(a.x, a.y, b.x, b.y) as distance
from tasks as a , engineers as b;
quit;

proc transpose data=want out=want_wide ;
by col1;
id col2;
var distance;
run;

你好我认识地球学家。我的主要问题是动态列,它是从engineers表生成的。我怎么才能得到那个格式。编辑我的答案。两份工作,我都会接受Reeza的答案。非常感谢你的帮助!请不要在将来发布图像,像下面的用户那样将您的数据作为一个数据步骤包含在内。这是。当我回答的时候已经很晚了,我一上床就意识到这要简单得多。