2017-04-09 56 views
0

我有一个数据集,看起来像这样:SAS - 从广角转换数据集高大使用数组

OBS  S1 S2 S3 
before 10 15 13 
after 5 7 8 

我试图使用数组在SAS将其转换为看起来像这样的表:

SUBJ BEFORE AFTER 
1  10  5 
2  15  7 
3  13  8 

我还是SAS的新手。我想,我需要建立一个具有形式的2x3阵列:

10 15 13 
5 7 8 

然后循环,但并分配值。

这是我迄今为止,但它仅捕获原始表的第一行:

DATA tall; 
    input obs $ score1-score3; 

    array rowscores(3) score1-score3; 
    array allscores(2,3) _TEMPORARY_; 

    do i=1 to 2; 
    do j=1 to 3; 
     allscores(i,j) = rowscores(j); 
    end; 
    end; 

    do k=1 to 3; 
    subj = k; 
    before = allscores(1,k); 
    after = allscores(2,k); 
    output; 
    end; 

    keep subj before after; 

    DATALINES; 
before 10 15 13 
after 5 7 8 
; 
RUN; 

我缺少什么?谢谢你的帮助!

+0

SAS一次只处理一行,而数组只是变量的快捷方式。这个解决方案取决于你知道数据的结构,在这一点你也可以输出新的数据集。在这种情况下,使用PROC TRANSPOSE而不是数组方法会更有效。 – Reeza

回答

1

对于您的数据步骤工作,您需要将您的INPUT语句移到您的第一个DO循环中。

要以这种方式进行这种转换,您需要在编译数据步骤之前知道很多关于数据的信息。我想你需要知道这个信息:

%let ncols=3 ; 
%let nrows=2 ; 
%let have_cols = s1-s3 ; 
%let want_cols = before after ; 

所以,如果你是知道的信息,那么你可以阅读整个数据集到一个临时数组,然后当你到最后它写回。

data want ; 
    set have end=eof; 
    array storage (&nrows,&ncols) _temporary_; 
    array cols &have_cols ; 
    do i=1 to &ncols; 
    storage(_n_,i)=cols(i) ; 
    end; 
    if eof then do; 
    do subj=1 to &ncols; 
     do j=1 to &nrows; 
     array want &want_cols ; 
     want(j) = storage(j,subj); 
     end; 
     output; 
    end; 
    end; 
    keep subj &want_cols ; 
run; 

仅仅使用PROC TRANSPOSE可能容易得多。

proc transpose data=have out=want ; 
    var s1-s3 ; 
    id obs ; 
run; 

然后,您可以将_NAME_变量更改为您的SUBJ变量或仅生成一个变量。

data want; 
    subj+1; 
    set want; 
run; 
+0

谢谢。它看起来像'PROC TRANSPOSE'是这个方法。 – waealu