跨 SAS 变量去重
de-duplicating across SAS variables
我已经根据条件转置了一些数据,现在我想跨变量删除重复数据。我会在转置数据之前完成此操作,但这只会给我留下每个变量的一个示例,我实际上需要进行某种条件重复数据删除。
我从这样的数据开始;
data have;
input ID Event level1 $;
datalines;
12345 9008 Activity1
12345 9008 Activity1
12345 9008 Activity1
12345 9008 Activity1
12345 1001 Activity2
12345 1001 Activity2
12345 1002 Activity3
12345 1002 Activity3
12345 6009 Activity4
12345 9009 Activity1
12345 9008 Activity1
12345 1001 Activity2
23145 9008 Activity1
23145 1001 Activity2
23145 1001 Activity2
23145 1001 Activity2
23145 1002 Activity3
23145 6009 Activity4
23145 1003 Activity5
23145 1003 Activity5
23145 1003 Activity5
23145 1004 Activity6
35762 9008 Activity1
35762 1001 Activity2
35762 1002 Activity3
35762 1002 Activity3
35762 6009 Activity4
35762 6009 Activity4
24958 9008 Activity1
24958 1002 Activity3
24958 1002 Activity3
24958 1002 Activity3
24958 9009 Activity1
24958 9009 Activity2
24958 9009 Activity3
;
run;
此数据根据 ID 和时间戳(此处未显示)排序。我想把它分成旅程,并根据第一个 9008 或 9009 代码转换数据。我已经通过使用以下代码设法做到了这一点
data AS.TENMAY_JOUR_TRANS;
set AS.TENMAY_LEVEL1;
if first.EVENT and EVENT = 9008 or EVENT = 9009 then;
proc transpose data=AS.TENMAY_LEVEL1
out=AS.TENMAY_JOUR_TRANS
name=Journey;
by ID;
var level1;
run;
run;
这就给了这个;
data have;
input ID Journey $ Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 Var10 Var11 Var12 Var13;
datalines;
12345 level1 Activity1 Activity1 Activity1 Activity1 Activity2 Activity2 Activity3 Activity3 Activity4
12345 level1 Activity1 Activity1 Activity2
23145 level1 Activity1 Activity2 Activity2 Activity2 Activity3 Activity4 Activity5 Activity5 Activity5 Activity6
35762 level1 Activity1 Activity2 Activity3 Activity3 Activity4 Activity4
24958 level1 Activity1 Activity3 Activity3 Activity3
24958 level1 Activity1 Activity2 Activity3
;
run;
不过我想讲这个;
data have ;
input ID Journey $ Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 Var10 Var11 Var12 Var13;
datalines;
12345 level1 Activity1 Activity2 Activity3 Activity4
23145 level1 Activity1 Activity2 Activity3 ACtivity4 Activity5 Activity6
35762 level1 Activity1 Activity3 Activity4
24958 level1 Activity1 Activity3
12345 level1 Activity1 Activity2
24958 level1 Activity1 Activity2 Activity3
;
run;
我无法删除初始数据的重复数据,因为我需要保留一些重复数据。我只需要在每个 ID
的第一个新的 9009 或 9008 之间对 level1 变量进行重复数据删除
我假设最好的方法是在 'PROC SORT' 语句中使用 'NODUP' 或 'NODUPKEY' 命令,我正在探索
这样的选项
data AS.TENMAY_JOUR_TRANS;
set AS.TENMAY_LEVEL11;
if first.EVENT and EVENT = Activity0 or EVENT = Activity1 then;
proc sort data= AS.TENMAY_JOUR_TRANS NODUP;
proc transpose data=AS2.TENMAY_LEVEL11
out=AS2.TENMAY_JOUR_TRANS
name=Journey;
by ID_INTERNET;
var level1;
run;
run;
run;
我不确定这是最好的方法,如果是这样,基本上我不确定是将 'PROC SORT' 步骤放在 'PROC TRANSPOSE' 步骤的内部还是外部。
非常感谢任何帮助。
谢谢!
您应该在转置数据之前删除重复数据。假设您有
data beforehave;
input ID Journey $ Activity $;
datalines;
12345 level1 Activity1
12345 level1 Activity1
12345 level1 Activity1
12345 level1 Activity2
12345 level1 Activity2
23145 level1 Activity1
23145 level1 Activity2
23145 level1 Activity2
;
RUN;
然后你必须在 Journey 和 Activity 之间进行重复数据删除:
PROC SORT data=beforehave; BY journey Activity nodupkey; RUN;
你可以转置。
抱歉没有提供更多代码:我今天无法访问我的 SAS...
那么让我们从大问题开始吧。您不能在数据步骤中混合过程。数据步骤基本上是对数据集的循环,允许您 alter/change/create table(s)。一个过程接受一个数据集并用它做一些事情。
所以你要做的是转置数据,删除重复项,然后转置回宽格式。
第 1 步:转置。
proc sort data=have;
by id journey;
run;
proc transpose data=have out=have_t(where=(col1 ^= "") drop=_name_);
by id journey;
var var:;
run;
这会旋转您的 table,创建一个名为 COL1
的列,其中包含所有 VAR* 变量中的值。 _NAME_
列包含旧列名。我们不想要那样,所以我们 drop
它。 out
数据集上的 where
过滤掉未填充的变量。
BY分组处理需要排序。
第 2 步,去除重复项。
proc sort data=have_t nodup;
by id journey;
run;
步骤 2.5,添加回 _NAME_
变量,这将是新的列名。
data have_t(drop=i);
set have_t;
by id journey;
retain i;
format _name_ .;
if first.journey then
i=0;
i = i + 1;
_name_ = "var" || strip(put(i,best.));
run;
这里我们创建一个计数变量,i
,并在每次旅程中递增计数。在输出中删除 i
变量。
第 3 步,向后移调
proc transpose data=have_t out=want(drop=_name_);
by id journey;
id _name_;
var col1;
run;
非常直接的转置,删除新的 _name_
变量。
3.5:如果你想要所有 13 Var
列。
data want;
format id best. journey . var1-var13 .;
set want;
run;
这定义了所有列,然后用 WANT 数据集中的值填充它,覆盖该数据集。
我设法通过为每种 Activity 类型的每个第一个条目创建一个等于 1 的标志,然后在我执行第一个转置之前基于此进行过滤来做到这一点。这是我用下面的代码做的
data AS2.TENMAY_LOGFLAG;
set AS2.TENMAY_LEVEL1;
if level1 = 'Activity' then logflag =1;
run;
然后我使用 EG 过滤 'where logflag = 1',然后进行 Transpose
我已经根据条件转置了一些数据,现在我想跨变量删除重复数据。我会在转置数据之前完成此操作,但这只会给我留下每个变量的一个示例,我实际上需要进行某种条件重复数据删除。
我从这样的数据开始;
data have;
input ID Event level1 $;
datalines;
12345 9008 Activity1
12345 9008 Activity1
12345 9008 Activity1
12345 9008 Activity1
12345 1001 Activity2
12345 1001 Activity2
12345 1002 Activity3
12345 1002 Activity3
12345 6009 Activity4
12345 9009 Activity1
12345 9008 Activity1
12345 1001 Activity2
23145 9008 Activity1
23145 1001 Activity2
23145 1001 Activity2
23145 1001 Activity2
23145 1002 Activity3
23145 6009 Activity4
23145 1003 Activity5
23145 1003 Activity5
23145 1003 Activity5
23145 1004 Activity6
35762 9008 Activity1
35762 1001 Activity2
35762 1002 Activity3
35762 1002 Activity3
35762 6009 Activity4
35762 6009 Activity4
24958 9008 Activity1
24958 1002 Activity3
24958 1002 Activity3
24958 1002 Activity3
24958 9009 Activity1
24958 9009 Activity2
24958 9009 Activity3
;
run;
此数据根据 ID 和时间戳(此处未显示)排序。我想把它分成旅程,并根据第一个 9008 或 9009 代码转换数据。我已经通过使用以下代码设法做到了这一点
data AS.TENMAY_JOUR_TRANS;
set AS.TENMAY_LEVEL1;
if first.EVENT and EVENT = 9008 or EVENT = 9009 then;
proc transpose data=AS.TENMAY_LEVEL1
out=AS.TENMAY_JOUR_TRANS
name=Journey;
by ID;
var level1;
run;
run;
这就给了这个;
data have;
input ID Journey $ Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 Var10 Var11 Var12 Var13;
datalines;
12345 level1 Activity1 Activity1 Activity1 Activity1 Activity2 Activity2 Activity3 Activity3 Activity4
12345 level1 Activity1 Activity1 Activity2
23145 level1 Activity1 Activity2 Activity2 Activity2 Activity3 Activity4 Activity5 Activity5 Activity5 Activity6
35762 level1 Activity1 Activity2 Activity3 Activity3 Activity4 Activity4
24958 level1 Activity1 Activity3 Activity3 Activity3
24958 level1 Activity1 Activity2 Activity3
;
run;
不过我想讲这个;
data have ;
input ID Journey $ Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 Var10 Var11 Var12 Var13;
datalines;
12345 level1 Activity1 Activity2 Activity3 Activity4
23145 level1 Activity1 Activity2 Activity3 ACtivity4 Activity5 Activity6
35762 level1 Activity1 Activity3 Activity4
24958 level1 Activity1 Activity3
12345 level1 Activity1 Activity2
24958 level1 Activity1 Activity2 Activity3
;
run;
我无法删除初始数据的重复数据,因为我需要保留一些重复数据。我只需要在每个 ID
的第一个新的 9009 或 9008 之间对 level1 变量进行重复数据删除我假设最好的方法是在 'PROC SORT' 语句中使用 'NODUP' 或 'NODUPKEY' 命令,我正在探索
这样的选项data AS.TENMAY_JOUR_TRANS;
set AS.TENMAY_LEVEL11;
if first.EVENT and EVENT = Activity0 or EVENT = Activity1 then;
proc sort data= AS.TENMAY_JOUR_TRANS NODUP;
proc transpose data=AS2.TENMAY_LEVEL11
out=AS2.TENMAY_JOUR_TRANS
name=Journey;
by ID_INTERNET;
var level1;
run;
run;
run;
我不确定这是最好的方法,如果是这样,基本上我不确定是将 'PROC SORT' 步骤放在 'PROC TRANSPOSE' 步骤的内部还是外部。
非常感谢任何帮助。
谢谢!
您应该在转置数据之前删除重复数据。假设您有
data beforehave;
input ID Journey $ Activity $;
datalines;
12345 level1 Activity1
12345 level1 Activity1
12345 level1 Activity1
12345 level1 Activity2
12345 level1 Activity2
23145 level1 Activity1
23145 level1 Activity2
23145 level1 Activity2
;
RUN;
然后你必须在 Journey 和 Activity 之间进行重复数据删除:
PROC SORT data=beforehave; BY journey Activity nodupkey; RUN;
你可以转置。 抱歉没有提供更多代码:我今天无法访问我的 SAS...
那么让我们从大问题开始吧。您不能在数据步骤中混合过程。数据步骤基本上是对数据集的循环,允许您 alter/change/create table(s)。一个过程接受一个数据集并用它做一些事情。
所以你要做的是转置数据,删除重复项,然后转置回宽格式。
第 1 步:转置。
proc sort data=have;
by id journey;
run;
proc transpose data=have out=have_t(where=(col1 ^= "") drop=_name_);
by id journey;
var var:;
run;
这会旋转您的 table,创建一个名为 COL1
的列,其中包含所有 VAR* 变量中的值。 _NAME_
列包含旧列名。我们不想要那样,所以我们 drop
它。 out
数据集上的 where
过滤掉未填充的变量。
BY分组处理需要排序。
第 2 步,去除重复项。
proc sort data=have_t nodup;
by id journey;
run;
步骤 2.5,添加回 _NAME_
变量,这将是新的列名。
data have_t(drop=i);
set have_t;
by id journey;
retain i;
format _name_ .;
if first.journey then
i=0;
i = i + 1;
_name_ = "var" || strip(put(i,best.));
run;
这里我们创建一个计数变量,i
,并在每次旅程中递增计数。在输出中删除 i
变量。
第 3 步,向后移调
proc transpose data=have_t out=want(drop=_name_);
by id journey;
id _name_;
var col1;
run;
非常直接的转置,删除新的 _name_
变量。
3.5:如果你想要所有 13 Var
列。
data want;
format id best. journey . var1-var13 .;
set want;
run;
这定义了所有列,然后用 WANT 数据集中的值填充它,覆盖该数据集。
我设法通过为每种 Activity 类型的每个第一个条目创建一个等于 1 的标志,然后在我执行第一个转置之前基于此进行过滤来做到这一点。这是我用下面的代码做的
data AS2.TENMAY_LOGFLAG;
set AS2.TENMAY_LEVEL1;
if level1 = 'Activity' then logflag =1;
run;
然后我使用 EG 过滤 'where logflag = 1',然后进行 Transpose