SAS:基于第三列将一列转换为两列

SAS:基于第三列将一列转换为两列,sas,transpose,Sas,Transpose,我有以下资料: data have; input id day $ col1; datalines; 84 day_1_x 302 84 day_1_y 443 18 day_2_x 774 18 day_2_y 281 61 day_5_x 488 61 day_5_y 564 ; run; 我想基于日期创建两个新列x和y 我天真的尝试并没有让我达到目的 data dont_quite_want; set have; length x 8 y 8; if

我有以下资料:

data have;
  input id  day $ col1;
datalines;
84 day_1_x 302
84 day_1_y 443
18 day_2_x 774
18 day_2_y 281
61 day_5_x 488
61 day_5_y 564
; 
run;
我想基于日期创建两个新列x和y

我天真的尝试并没有让我达到目的

  data dont_quite_want;
    set have;
    length x 8 y 8;

    if scan(day, 3, '_') = 'x' then x = col1;
    else y = col1; 

  run;

| Obs | id | day     | col1 | x   | y   |
|-----+----+---------+------+-----+-----|
|   1 | 84 | day_1_x |  302 | 302 | .   |
|   2 | 84 | day_1_y |  443 | .   | 443 |
|   3 | 18 | day_3_x |  774 | 774 | .   |
|   4 | 18 | day_3_y |  281 | .   | 281 |
|   5 | 61 | day_5_x |  488 | 488 | .   |
|   6 | 61 | day_5_y |  564 | .   | 564 |
|-----+----+---------+------+-----+-----|

如果有一种一次性的方法,我不会感到惊讶,但我想知道,如何将转换分解为单独的步骤?

我可能会这样做,即处理转置-这需要转置,如果这对您很重要,您可以在数据上一次性完成

data for_transpose/view=for_transpose;
  set have(rename=day=long_day);
  day = scan(long_day,2,'_');
  varname = scan(long_day,3,'_');
run;

proc transpose data=for_transpose out=want;
  by id day notsorted;
  var col1;
  id varname;
run;
然而,在一个数据步骤中也很容易做到——只是更加硬编码

data want;
    set have(rename=day=long_day);
    by id notsorted; *your two ID rows still need to be adjacent;
    length x 8 y 8;
    retain x y day;
    if first.id then call missing(x,y);  *reset them;
    day = scan(long_day,2,'_');
    if scan(long_day, 3, '_') = 'x' then x = col1;
    else y = col1; 
    if last.id then output;
run;

我可能会这样做的方式是处理转置-这需要转置,如果这对您很重要的话,您可以在一次数据传递中完成

data for_transpose/view=for_transpose;
  set have(rename=day=long_day);
  day = scan(long_day,2,'_');
  varname = scan(long_day,3,'_');
run;

proc transpose data=for_transpose out=want;
  by id day notsorted;
  var col1;
  id varname;
run;
然而,在一个数据步骤中也很容易做到——只是更加硬编码

data want;
    set have(rename=day=long_day);
    by id notsorted; *your two ID rows still need to be adjacent;
    length x 8 y 8;
    retain x y day;
    if first.id then call missing(x,y);  *reset them;
    day = scan(long_day,2,'_');
    if scan(long_day, 3, '_') = 'x' then x = col1;
    else y = col1; 
    if last.id then output;
run;

这是转置版本@乔给了你完整的数据步骤

/*Pull out the day and variable name from the day column
  Use and index so you don't have to sort*/
data have(index=(id));
set have;
d = input(scan(day,2,"_"),best.);
_name_ = scan(day,3,"_");
run;

/*Transpose the data keeping the variables you want and renaming
  as needed */
proc transpose data=have out=want(drop=_name_ rename=(d=day));
by id d;
var col1;
id _name_;
run;

这是转置版本@乔给了你完整的数据步骤

/*Pull out the day and variable name from the day column
  Use and index so you don't have to sort*/
data have(index=(id));
set have;
d = input(scan(day,2,"_"),best.);
_name_ = scan(day,3,"_");
run;

/*Transpose the data keeping the variables you want and renaming
  as needed */
proc transpose data=have out=want(drop=_name_ rename=(d=day));
by id d;
var col1;
id _name_;
run;