在SAS

时间:2017-01-04 17:25:35

标签: sas sas-iml

如何在SAS中创建数据集的子集,我想在此之前确定变量的平均值,方差和观测数量?

示例:

OBS  NAME  x1 x2
1    Bill  3  2
2    James 4  5
3    Rick  5  6
4    Bob   3  7
5    Clas  5  2
6    Brye  2  9
7    Mann  8  5
8    Pids  4  8
9    Tony  0  7
10   Lou   2  6 

假设我想要一个包含3个观察值的子集,平均值(x1)= 4,并且std(x1)= 0.95。我如何在SAS中创建此子集?

我宁愿不使用proc方法做一些事情并反复猜测/检查。任何帮助表示赞赏!

更新:创建一个逻辑模型,预测观察结果是在治疗组还是对照组。然后取最高概率的前10%治疗组,但不包括在治疗组中,基本上用作对照组。

1 个答案:

答案 0 :(得分:0)

这是knapsack problem的变体。您正在尝试查找对象的子集(此处为3个人),以使其属性接近某些指定的目标值(此处为和[或平均值]并校正平方和[或std dev])。这也称为时刻匹配问题。

如上所述,问题没有明确定义。您需要指定一个目标函数来最小化。例如,您可以选择该功能 (mean-target_mean)** 2 +(stdDev - target_stdDev)** 2 其中(mean,stdDev)是每个尺寸为3的样品的时刻。

对于小集(如您的示例中),您可以完全枚举“N choose 3”组合以确定要选择的组合。有关提示,请参阅文章"Generate combinations in SAS"。例如,在SAS / IML中,您可以按如下方式解决所述问题:

data A;
length NAME $5.;
input NAME $ x1 x2;
datalines;
Bill  3  2
James 4  5
Rick  5  6
Bob   3  7
Clas  5  2
Brye  2  9
Mann  8  5
Pids  4  8
Tony  0  7
Lou   2  6 
;

proc iml;
use A; read all var {Name x1}; close;

N = nrow(x1);              /* number of obs */          
k = 3;                     /* size of subset */
targetMean = 4;
targetStd = 0.95;

idx = allcomb(N, k);       /* all M='N choose 3' combinations */
X = shape( x1[idx], nrow(idx) );
mean = mean(X`);           /* 1 x M vector of sample means */
std  = std(X`);            /* 1 x M vector of sample std devs */
objective = (mean - targetMean)##2 + (std - targetStd)##2;
minVal = objective[><];    /* minimize objective */
minIdx = objective[>:<];   /* a sample that achieves minimum */

sampNames = Name[idx[minIdx,]];
sampVals = x1[idx[minIdx,]];
print sampVals[rowname=sampNames];

当然,可能有多个解决方案。这个例子有8个解决方案。

对于存在N个项目并且您想要大小为k的子集并且“N选择k”非常大的问题,您可以使用RANCOMB函数(或PROC SURVEYSELECT,如有人提到的那样)生成随机子集)。或者,您可以将此问题表述为优化问题。您可以使用SAS / OR或SAS / IML中的算法来解决它。对于中等大小的子集,您可以use genetic algorithms in SAS/IML,这对背包式问题很有用。