2017-12-06 2 views
1

ich einen Datensatz haben, wie folgendverbinden die SAS datases seitlich, horizontal

ID A1 A2 A3 
A 1.2 1.5 1 
A 1.3 1.7 1.3 
A 1.4 1.8 1.7 
B 1.5 1.8 1.9 
B 1.6 1.7 1.0 

und führen die ich suche ist

A 1.2 1.5 1 1.3 1.7 1.3 1.4 1.8 1.7 

Ich weiß, dass SAS Variablennamen nicht wiederholt werden kann, aber wenn ich versuchte, Proc SQL, mit innerem Join gibt es mir mehr Zeilen.

+0

Wissen Sie im Voraus, wie hoch die maximale Anzahl von Zeilen pro ID ist? Dies ist auch sehr schwierig, wenn Sie SQL verwenden, es sei denn, Sie haben auch eine andere Variable in Ihrem Dataset, die für jede ID von 1 in der ersten Zeile beginnt und für jede fortlaufende Zeile mit derselben ID um 1 erhöht. – user667489

Antwort

2

Ein SAS-Datastep ist hier die beste Option. Richten Sie ein Array ein, um jeden Wert nacheinander zu lesen, einschließlich über mehrere Zeilen, speichert sie in einem neuen Array und gibt sie erst nach dem Lesen der letzten ID aus.

Das einzige Problem ist, dass Sie die maximale Anzahl der Werte wissen müssen, die eine ID nehmen kann, die nrows x ncols (nicht nur die Anzahl der Zeilen) sein wird. In Ihrem Beispiel ist der Anser 9, da ID A 3 Zeilen und 3 Spalten hat. Eine Lösung besteht darin, die Anzahl der Elemente im neuen Array so festzulegen, dass sie höher ist, als Sie für erforderlich halten. Es bedeutet lediglich, dass am Ende des Datasets einige leere Spalten vorhanden sind. Ich habe den Wert auf 10 in meinem Code unten festgelegt.

data have; 
input ID $ A1 A2 A3; 
datalines; 
A 1.2 1.5 1 
A 1.3 1.7 1.3 
A 1.4 1.8 1.7 
B 1.5 1.8 1.9 
B 1.6 1.7 1.0 
; 
run; 

data want; 
set have; 
by id; 
retain newA1-newA10; /* keep values across rows */ 
array oldvars{*} A: ; /* array of existing variables */ 
array newvars{*} newA1-newA10; /* array of new variables */ 
if first.id then do; /* reset counter and array values when ID changes */ 
    counter=0; 
    call missing(of newA1-newA10); 
    end; 
do i = 1 to dim(oldvars); /* loop through each value and store in new array */ 
    counter+1; 
    newvars{counter} = oldvars{i}; 
end; 
if last.id then output; /* only output after last ID is read */ 
drop A: counter i; /* drop unwanted variables */ 
run; 
1

Ähnlich wie bei Longfish, aber als DOW. In der DOW-Verarbeitung müssen Sie die Array-Elemente jedoch nicht beibehalten, da das breite Array innerhalb einer einzelnen Iteration der impliziten Data Step-Schleife aufgefüllt wird.

* measure the data; 
data _null_; 
    set have end=last_row; 
    by ID; 
    array A A1-A3; 
    retain max_group_size 0; 
    if first.ID then group_size = 0; 
    group_size + 1; * implicit retain; 
    if last.ID then max_group_size = max (max_group_size, group_size); 
    if last_row then do; 
    call symputx ('wide_count', max_group_size * dim(A)); 
    end; 
run; 

* extrude the data; 
data want(keep=ID AX:); 
    do _wide_index = 0 by 0 until (last.id); /* initialize wide_index and loop over group */ 
    set have; 
    by ID; 

    array A A1-A3; 
    array AX AX1-AX&wide_count; * X is for eXtruded :) ; 

    do _small_index = 1 to dim (A); 
     _wide_index + 1; 
     AX [ _wide_index ] = A [ _small_index ]; 
    end; 
    end; 
    * implicit output occurs here because there is no explicit output statement elsewhere in the step; 
run;