Csv SAS:如何找到每个变量列的第二高条目?
我有一个CSV格式的数据集,如下所示:Csv SAS:如何找到每个变量列的第二高条目?,csv,sas,Csv,Sas,我有一个CSV格式的数据集,如下所示: Policy_Number,var1,var2,var3,Exposure 1,B,H,J,191 2,B,F,Unknown,174 3,C,Unknown,I,153 4,B,G,L,192 5,Unknown,E,Unknown,184 6,D,E,K,113 7,C,Unknown,I,140 8,A,H,I,133 9,C,F,I,194 10,Unknown,G,Unknown,105 11,B,H,L,172 12,A,Unknown,I,1
Policy_Number,var1,var2,var3,Exposure
1,B,H,J,191
2,B,F,Unknown,174
3,C,Unknown,I,153
4,B,G,L,192
5,Unknown,E,Unknown,184
6,D,E,K,113
7,C,Unknown,I,140
8,A,H,I,133
9,C,F,I,194
10,Unknown,G,Unknown,105
11,B,H,L,172
12,A,Unknown,I,198
13,D,E,K,155
14,Unknown,G,K,177
15,B,H,Unknown,100
16,D,Unknown,J,176
17,B,E,I,112
18,Unknown,E,J,192
19,C,Unknown,K,146
20,C,G,Unknown,187
data try2;
infile 'complex.csv' dsd dlm = ',' FIRSTOBS = 2;
Length Policy_Number Var1 $ 10 Var2 $ 10 Var3 $ 10 Exposure 3;
input Policy_Number $ Var1 $ Var2 $ Var3 $ Exposure;
run;
proc sort data = try2;
by Var3 descending Exposure;
run;
data need2;
set try2;
by Var1;
if first.var1 then n=0;
n+1;
if n=1 then output;
if n=2 then output;
run;
我想找出每个变量的最高和第二高“暴露”值,即Var1、Var2、Var3
随后,输出文件必须如下所示:
VariableName VariableValue Max_Exposure Exposure_Percentage
Var1 A 198
Var1 A 133
Var1 B 192
Var1 B 191
Var1 C 194
Var1 C 187
Var1 D 176
Var1 D 155
Var1 Unknown 192
Var1 Unknown 184
Var2 E 192
Var2 E 184
Var2 F 194
Var2 F 174
Var2 G 192
Var2 G 187
Var2 H 191
Var2 H 172
Var2 Unknown 198
Var2 Unknown 176
Var3 I 198
Var3 I 194
Var3 J 192
Var3 J 191
Var3 K 177
Var3 K 155
Var3 L 192
Var3 L 187
Var3 Unknown 184
Var3 Unknown 194
其中,暴露百分比是每个可变值的暴露百分比
我是用一种非常原始的方法来做的。我创建了3个表,找出每个表的最大曝光量和第二最大曝光量,然后合并这3个表。但是如果VariableName增加,即在数据中引入更多列,那么我的方法将失败。其代码如下所示:
Policy_Number,var1,var2,var3,Exposure
1,B,H,J,191
2,B,F,Unknown,174
3,C,Unknown,I,153
4,B,G,L,192
5,Unknown,E,Unknown,184
6,D,E,K,113
7,C,Unknown,I,140
8,A,H,I,133
9,C,F,I,194
10,Unknown,G,Unknown,105
11,B,H,L,172
12,A,Unknown,I,198
13,D,E,K,155
14,Unknown,G,K,177
15,B,H,Unknown,100
16,D,Unknown,J,176
17,B,E,I,112
18,Unknown,E,J,192
19,C,Unknown,K,146
20,C,G,Unknown,187
data try2;
infile 'complex.csv' dsd dlm = ',' FIRSTOBS = 2;
Length Policy_Number Var1 $ 10 Var2 $ 10 Var3 $ 10 Exposure 3;
input Policy_Number $ Var1 $ Var2 $ Var3 $ Exposure;
run;
proc sort data = try2;
by Var3 descending Exposure;
run;
data need2;
set try2;
by Var1;
if first.var1 then n=0;
n+1;
if n=1 then output;
if n=2 then output;
run;
请告诉我这些问题的可能解决办法。
提前感谢。所以首先定义有多少变量:
%let num_vars=3;
启动datastep并定义数组,以保存第一次观察到的变量名以及每行的值
data IN(keep=VARIABLENAME VARIABLEVALUE EXPOSURE);
array VAR(&num_vars) $10.;
array VAL(&num_vars) $10.;
retain VAR1-VAR&num_vars.;
length VARIABLENAME VARIABLEVALUE $8 EXPOSURE 8.;
infile cards dsd ;
if _n_ = 1 then do;
input;
do i = 1 to &num_vars.;
VAR(i) = scan(_infile_,i+1,",");
end;
end;
这是一个输入步骤,读取变量,然后将其存储在数组中,然后在下面输出:
input POLICY_NUMBER @ ;
do i = 1 to &num_vars;
VARIABLENAME=VAR(i);
input VAL(i) $ @;
end;
input EXPOSURE;
do i = 1 to &num_vars;
VARIABLENAME=VAR(i);
VARIABLEVALUE=VAL(i);
output;
end;
cards;
Policy_Number,var1,var2,var3,Exposure
1,B,H,J,191
2,B,F,Unknown,174
3,C,Unknown,I,153
4,B,G,L,192
5,Unknown,E,Unknown,184
6,D,E,K,113
7,C,Unknown,I,140
8,A,H,I,133
9,C,F,I,194
10,Unknown,G,Unknown,105
11,B,H,L,172
12,A,Unknown,I,198
13,D,E,K,155
14,Unknown,G,K,177
15,B,H,Unknown,100
16,D,Unknown,J,176
17,B,E,I,112
18,Unknown,E,J,192
19,C,Unknown,K,146
20,C,G,Unknown,187
;
run;
按所需顺序对变量进行排序:
proc sort data=IN; by VARIABLENAME VARIABLEVALUE descending EXPOSURE ; run;
通过使用CNT变量保留max values的前两个实例
data GET_MAX(drop=CNT);
set IN;
by VARIABLENAME VARIABLEVALUE descending EXPOSURE;
if first.VARIABLEVALUE then call missing(of CNT);
CNT+1;
if CNT in (1,2);
run;
然后计算您的百分比:
proc sql;
create table OUT as
select VARIABLENAME
, VARIABLEVALUE
, EXPOSURE
, (EXPOSURE/sum(EXPOSURE))*100 as EXPOSURE_PERCENTAGE format=8.2
from
GET_MAX
group by 1,2
;quit;
要使用proc summary获取总和,请执行以下操作:
proc summary data=GET_MAX nway;
var EXPOSURE ;
class VARIABLENAME VARIABLEVALUE;
output out=work.TEST(drop=_TYPE_ _FREQ_ )
sum=EXPOSURE_SM ;
run;
因此,首先定义有多少个变量:
%let num_vars=3;
启动datastep并定义数组,以保存第一次观察到的变量名以及每行的值
data IN(keep=VARIABLENAME VARIABLEVALUE EXPOSURE);
array VAR(&num_vars) $10.;
array VAL(&num_vars) $10.;
retain VAR1-VAR&num_vars.;
length VARIABLENAME VARIABLEVALUE $8 EXPOSURE 8.;
infile cards dsd ;
if _n_ = 1 then do;
input;
do i = 1 to &num_vars.;
VAR(i) = scan(_infile_,i+1,",");
end;
end;
这是一个输入步骤,读取变量,然后将其存储在数组中,然后在下面输出:
input POLICY_NUMBER @ ;
do i = 1 to &num_vars;
VARIABLENAME=VAR(i);
input VAL(i) $ @;
end;
input EXPOSURE;
do i = 1 to &num_vars;
VARIABLENAME=VAR(i);
VARIABLEVALUE=VAL(i);
output;
end;
cards;
Policy_Number,var1,var2,var3,Exposure
1,B,H,J,191
2,B,F,Unknown,174
3,C,Unknown,I,153
4,B,G,L,192
5,Unknown,E,Unknown,184
6,D,E,K,113
7,C,Unknown,I,140
8,A,H,I,133
9,C,F,I,194
10,Unknown,G,Unknown,105
11,B,H,L,172
12,A,Unknown,I,198
13,D,E,K,155
14,Unknown,G,K,177
15,B,H,Unknown,100
16,D,Unknown,J,176
17,B,E,I,112
18,Unknown,E,J,192
19,C,Unknown,K,146
20,C,G,Unknown,187
;
run;
按所需顺序对变量进行排序:
proc sort data=IN; by VARIABLENAME VARIABLEVALUE descending EXPOSURE ; run;
通过使用CNT变量保留max values的前两个实例
data GET_MAX(drop=CNT);
set IN;
by VARIABLENAME VARIABLEVALUE descending EXPOSURE;
if first.VARIABLEVALUE then call missing(of CNT);
CNT+1;
if CNT in (1,2);
run;
然后计算您的百分比:
proc sql;
create table OUT as
select VARIABLENAME
, VARIABLEVALUE
, EXPOSURE
, (EXPOSURE/sum(EXPOSURE))*100 as EXPOSURE_PERCENTAGE format=8.2
from
GET_MAX
group by 1,2
;quit;
要使用proc summary获取总和,请执行以下操作:
proc summary data=GET_MAX nway;
var EXPOSURE ;
class VARIABLENAME VARIABLEVALUE;
output out=work.TEST(drop=_TYPE_ _FREQ_ )
sum=EXPOSURE_SM ;
run;
我已经使用
proc summary
来计算最高2个风险,使用idgroup
功能。这会将值放在两列而不是两行中,因此需要后续的数据步骤将数据转换为所需的格式。但是,初始布局确实使计算数据步骤中的百分比更容易
/* input csv data */
data try2;
infile datalines dsd;
Length Policy_Number Var1 $ 10 Var2 $ 10 Var3 $ 10 Exposure 3;
input Policy_Number $ Var1 $ Var2 $ Var3 $ Exposure;
datalines;
1,B,H,J,191
2,B,F,Unknown,174
3,C,Unknown,I,153
4,B,G,L,192
5,Unknown,E,Unknown,184
6,D,E,K,113
7,C,Unknown,I,140
8,A,H,I,133
9,C,F,I,194
10,Unknown,G,Unknown,105
11,B,H,L,172
12,A,Unknown,I,198
13,D,E,K,155
14,Unknown,G,K,177
15,B,H,Unknown,100
16,D,Unknown,J,176
17,B,E,I,112
18,Unknown,E,J,192
19,C,Unknown,K,146
20,C,G,Unknown,187
;
run;
/* calculate highest 2 exposures for each variable */
proc summary data=try2;
class var: ;
ways 1;
output out=want (drop=_:) idgroup(max(exposure) out[2] (exposure)=) / autoname;
run;
/* merge Var fields into 1 and output 1 row per exposure */
data want1;
set want;
_expsum = sum(of exposure:); /* sum exposures to calculate percentages later on */
array vars var:; /* create array of Var variables */
array exp exposure:; /* create array of Exposure variables */
do i=1 to dim(vars); /* loop through Var variables and keep non-missing values */
if not missing(vars{i}) then do;
variablename=vname(vars{i});
variablevalue=vars{i};
end;
end;
do j=1 to dim(exp); /* loop through Exposures, output each one and calculate percentage of total */
max_exposure = exp{j};
exposure_percentage = exp{j}/_expsum;
output;
end;
format exposure_percentage percent10.1;
drop var1--var3 exposure_1 exposure_2 _expsum i j; /* drop unwanted variables */
run;
/* sort data in required order */
proc sort data=want1;
by variablename variablevalue descending max_exposure;
run;
我已经使用
proc summary
来计算最高2个风险,使用idgroup
功能。这会将值放在两列而不是两行中,因此需要后续的数据步骤将数据转换为所需的格式。但是,初始布局确实使计算数据步骤中的百分比更容易
/* input csv data */
data try2;
infile datalines dsd;
Length Policy_Number Var1 $ 10 Var2 $ 10 Var3 $ 10 Exposure 3;
input Policy_Number $ Var1 $ Var2 $ Var3 $ Exposure;
datalines;
1,B,H,J,191
2,B,F,Unknown,174
3,C,Unknown,I,153
4,B,G,L,192
5,Unknown,E,Unknown,184
6,D,E,K,113
7,C,Unknown,I,140
8,A,H,I,133
9,C,F,I,194
10,Unknown,G,Unknown,105
11,B,H,L,172
12,A,Unknown,I,198
13,D,E,K,155
14,Unknown,G,K,177
15,B,H,Unknown,100
16,D,Unknown,J,176
17,B,E,I,112
18,Unknown,E,J,192
19,C,Unknown,K,146
20,C,G,Unknown,187
;
run;
/* calculate highest 2 exposures for each variable */
proc summary data=try2;
class var: ;
ways 1;
output out=want (drop=_:) idgroup(max(exposure) out[2] (exposure)=) / autoname;
run;
/* merge Var fields into 1 and output 1 row per exposure */
data want1;
set want;
_expsum = sum(of exposure:); /* sum exposures to calculate percentages later on */
array vars var:; /* create array of Var variables */
array exp exposure:; /* create array of Exposure variables */
do i=1 to dim(vars); /* loop through Var variables and keep non-missing values */
if not missing(vars{i}) then do;
variablename=vname(vars{i});
variablevalue=vars{i};
end;
end;
do j=1 to dim(exp); /* loop through Exposures, output each one and calculate percentage of total */
max_exposure = exp{j};
exposure_percentage = exp{j}/_expsum;
output;
end;
format exposure_percentage percent10.1;
drop var1--var3 exposure_1 exposure_2 _expsum i j; /* drop unwanted variables */
run;
/* sort data in required order */
proc sort data=want1;
by variablename variablevalue descending max_exposure;
run;
问题基本上是总结数据,并为此发布新帖子@基思的问题基本上是总结数据,为此开始了一篇新的帖子@Keithmaybe这个新问题可能会让你对我想要的东西有更广阔的视野。请查看SQL添加内容,该内容将给出您的百分比,并回答您的新问题(没有过程摘要,对不起!)。谢谢您的帮助,伙计。:)虽然新问题是我的最终要求。但答案总是令人感激的。:)没问题。问题是你在寻找一个过程总结到底有多远?你不能用它读取数据,我也不认为你能用它得到前两个值。。。您是否希望它专门用于最终输出,因为在这种情况下,您可以在两个数据步骤内完成所有的前期工作。我只需要这里提到的输出。之后,我将得到它的子集,并将张贴我得到的结果。如果你对那部分有什么想法,一定要告诉我。我很高兴能从中得到答案。:)也许这个新问题会让你对我想要的东西有更广阔的视野。请查看SQL添加内容,该内容将给出您的百分比,并回答您的新问题(没有过程摘要,对不起!)。谢谢您的帮助,伙计。:)虽然新问题是我的最终要求。但答案总是令人感激的。:)没问题。问题是你在寻找一个过程总结到底有多远?你不能用它读取数据,我也不认为你能用它得到前两个值。。。您是否希望它专门用于最终输出,因为在这种情况下,您可以在两个数据步骤内完成所有的前期工作。我只需要这里提到的输出。之后,我将得到它的子集,并将张贴我得到的结果。如果你对那部分有什么想法,一定要告诉我。我很高兴能从中得到答案。:)