2017-11-21 5 views
1

데이터 세트 types100 rows x 61 columns입니다. 첫 번째 열은 Type_ID을 나타내고 나머지 열은 시간과 관련됩니다.다른 데이터 세트의 SAS 다차원 배열 초기화

다른 데이터 단계 calculate; types의 100 행 60 열 데이터로 초기화되는 다차원 배열 timeType{100,60}을 생성하려고합니다.

지금까지 읽은 모든 SAS 설명서는 명시 적 열 참조를 사용하여 다차원 배열을 초기화하고 배열은 열을 배열 크기에 맞 춥니 다.

데이터 집합을 효과적으로 배열에 읽어 들일 수 있습니까?

+0

60 개의 열이 모두 숫자입니까? 예를 들어, 3 행 5 열로 샘플 데이터를 게시하는 것이 좋습니다. – Quentin

+1

배열에 6,000 개의 변수를 모두로드하려는 이유가 무엇입니까? 임시 배열입니까, 아니면 데이터 세트에 저장 하시겠습니까? 여기에 유스 케이스는 무엇입니까? 매우 일반적인 데이터 구조가 아니며 SAS에서 매우 쉽게 사용되는 2 차원 배열보다 일을 처리하는 다른 방법이있을 수 있습니다. – Joe

+0

나는 많은 금액에 걸쳐 60 개의 할인율을 적용하고 있습니다. 현재 4 가지 할인 유형이 있습니다. 그 솔루션을 코딩했지만 _n_ 다른 할인 유형 및 _m_ 다른 할인 기간을 일반화하는 방법을 찾지 못했습니다. 나는 100K 이상의 금액을 가지고 있으며 현재 가치 계산은 트랜잭션의 다른 구성 요소에 대해 여러 번 수행해야한다. (나는 다양한 트랜잭션 구성 요소를 처리하기 위해 자체 생성 코드를 사용한다.)하지만 현재 가치를 계산하는 핵심 부분은 생각하는 것이 더 효율적 일 것입니다. – candlejack

답변

1

나는 배열에 큰 편이 아니며, 아래에서는 어떤 스타일 포인트도 얻지 못할 것이다. 그러나 시작일 뿐이다.

기본 접근법은 DoW 루프를 사용하여 모든 데이터를 2 차원 배열로 읽는 것입니다.

data have; 
    do TypeID=1 to 5; 
    p1=10*TypeID; 
    p2=100*TypeID; 
    p3=1000*TypeID; 
    output; 
    end; 
run; 

data _null_; 
    *DOW loop to read data into array; 
    do until (last); 
    set have end=last; 

    array timeType(5,3) _temporary_; 
    array p{*} p:; 

    row++1; 
    do col=1 to dim(p); 
     timeType{row,col}=p{col}; 
    end; 
    end; 

    *PUT the values of the array to the log, for checking; 
    do i=1 to dim1(timeType); 
    do j=1 to dim2(timeType); 
     put timeType{i,j}=; 
    end; 
    end; 

    drop row col i j; 
run; 
2

Quentin과 매우 유사합니다. 나는 Dorfman을 독서 루프로 유명한 건축물 do _n_ = 1 by 1 until(end)으로 만들었다.

data types; 
    do type_id = 1 to 100; 
    array x x1-x60; 
    do over x; global_counter+1; x = global_counter; end; 
    output; 
    end; 
run; 

data calculate(keep=testid result) typesread_check(keep=x1-x60); 

    array matrix(100,60) _temporary_; 

    * load matrix; 
    do _n_ = 1 by 1 until (end); 
    set types end=end; 
    array x x1-x60; * this array is composed of variables that are filled by the SET operation; 
    do _i_ = 1 to dim(x); 
     matrix(_n_,_i_) = x(_i_); 
    end; 
    end; 

    * unload matrix to check load with COMPARE; 
    * can be commented out/removed after confidence established; 
    do _n_ = 1 to 100; 
    do _i_ = 1 to 60; 
     x(_i_) = matrix(_n_,_i_); 
    end; 
    output typesread_check; 
    end; 

    * perform computations that output; 
    testid = 1; 
    result = sum(of matrix(*)); 

    output calculate; 
run; 

* output is zero rows of differences. That means the matrix was populated correctly; 
proc compare noprint data=types(drop=type_id) compare=typesread_check out=diff outnoequal; 
run; 

이 유형의 데이터에 따라 계산 결과를 유지하려면

_temporary_ 옵션을 제거하십시오. keep (testid result matrix:) 행렬 (100,60)에 해당하는 6,000 개의 추가 열을 갖는 출력을 얻으려면

0

대신 해시 객체를 사용하십시오. 먼저 "매트릭스"가 아닌 일반 데이터 세트로 요금을 바꾸십시오. 아니면 그냥 원래대로 만들 수 있습니다.

data rates; 
    do type=1 to 3 ; 
    do time=1 to 3 ; 
     input rate @@ ; 
     output; 
    end; 
    end; 
cards; 
.1 .2 .3 .4 .5 .6 .7 .8 .9 
; 

이제 예제 데이터를 만들어 보겠습니다. 나는 rate 테이블의 레코드와 일치하지 않는 레코드 하나를 포함 시켰습니다.

data have ; 
    input type time amount expected; 
cards; 
1 2 100 20 
2 3 100 60 
4 5 100 . 
; 

이제 HASH 오브젝트로 속도를로드 전류와 TYPE TIME 결합에 대한 비율을 찾을 .FIND() 메소드를 사용한다.

data want ; 
    set have ; 
    if _N_ = 1 then do; 
    declare hash h(dataset:"rates"); 
    rc = h.defineKey('type','time'); 
    rc = h.defineData('rate'); 
    rc = h.defineDone(); 
    call missing(rate); 
    drop rc; 
    end; 
    if (0=h.find()) then payment=amount*rate; 
run; 

결과.

Obs type time amount expected payment rate 

1  1  2  100  20   20  0.2 
2  2  3  100  60   60  0.6 
3  4  5  100   .   .  . 
관련 문제