在 SAS 中创建控制组
Creating a Control Group in SAS
我如何在 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 个观测值的子集,mean(x1) = 4,std(x1) = 0.95。我将如何在 SAS 中创建这个子集?
我宁愿不做一些使用 proc 手段和 guess/check 重复的事情。任何帮助表示赞赏!
更新:创建了一个逻辑模型来预测观察结果是在治疗组还是对照组。然后抽取前10%概率最高的在治疗组,但没有被纳入治疗组,本质上作为对照组。
这是 knapsack problem 的变体。您正在尝试找到对象的子集(此处为 3 人),以便它们的属性接近某些指定的目标值(此处为总和 [或均值] 和校正平方和 [或标准偏差])。这也称为矩匹配问题。
如前所述,问题没有明确定义。您需要指定一个 objective 函数来最小化。例如,您可以选择函数
(mean-target_mean)**2 + (stdDev - target_stdDev)**2
其中 (mean, stdDev) 是每个大小为 3 的样本的时刻。
对于小集合(如您的示例),您可以对 "N choose 3" 组合进行完整枚举以确定选择哪个组合。有关提示,请参阅文章 "Generate combinations in SAS"。例如,在 SAS/IML 中,您可以按如下方式解决所述问题:
data A;
length NAME .;
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 choose k' 过大的问题,您可以使用 RANCOMB 函数(或 PROC SURVEYSELECT,如有人提到)。或者,您可以将此问题表述为优化问题。您可以使用 SAS/OR 或 SAS/IML 中的算法来解决它。对于中等大小的子集,您可以 use genetic algorithms in 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 个观测值的子集,mean(x1) = 4,std(x1) = 0.95。我将如何在 SAS 中创建这个子集?
我宁愿不做一些使用 proc 手段和 guess/check 重复的事情。任何帮助表示赞赏!
更新:创建了一个逻辑模型来预测观察结果是在治疗组还是对照组。然后抽取前10%概率最高的在治疗组,但没有被纳入治疗组,本质上作为对照组。
这是 knapsack problem 的变体。您正在尝试找到对象的子集(此处为 3 人),以便它们的属性接近某些指定的目标值(此处为总和 [或均值] 和校正平方和 [或标准偏差])。这也称为矩匹配问题。
如前所述,问题没有明确定义。您需要指定一个 objective 函数来最小化。例如,您可以选择函数 (mean-target_mean)**2 + (stdDev - target_stdDev)**2 其中 (mean, stdDev) 是每个大小为 3 的样本的时刻。
对于小集合(如您的示例),您可以对 "N choose 3" 组合进行完整枚举以确定选择哪个组合。有关提示,请参阅文章 "Generate combinations in SAS"。例如,在 SAS/IML 中,您可以按如下方式解决所述问题:
data A;
length NAME .;
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 choose k' 过大的问题,您可以使用 RANCOMB 函数(或 PROC SURVEYSELECT,如有人提到)。或者,您可以将此问题表述为优化问题。您可以使用 SAS/OR 或 SAS/IML 中的算法来解决它。对于中等大小的子集,您可以 use genetic algorithms in SAS/IML,这对类似背包的问题很有用。