Csv SAS:如何找到每个变量列的第二高条目?

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

我有一个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,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添加内容,该内容将给出您的百分比,并回答您的新问题(没有过程摘要,对不起!)。谢谢您的帮助,伙计。:)虽然新问题是我的最终要求。但答案总是令人感激的。:)没问题。问题是你在寻找一个过程总结到底有多远?你不能用它读取数据,我也不认为你能用它得到前两个值。。。您是否希望它专门用于最终输出,因为在这种情况下,您可以在两个数据步骤内完成所有的前期工作。我只需要这里提到的输出。之后,我将得到它的子集,并将张贴我得到的结果。如果你对那部分有什么想法,一定要告诉我。我很高兴能从中得到答案。:)