SAS程序,如何在没有IML的情况下基于两个表进行计算
我一直在为sas中的一些矩阵计算而挣扎。 我有两个表,都包含经度和纬度信息 任务表 工程师表: 我的输出目标是任务和工程师之间的距离 距离: 由于SAS/IML的额外成本,我没有在本地安装。有没有人有这样做的经验 另外,R中的代码很简单,如下所示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)){
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的答案。非常感谢你的帮助!请不要在将来发布图像,像下面的用户那样将您的数据作为一个数据步骤包含在内。这是。当我回答的时候已经很晚了,我一上床就意识到这要简单得多。