2017-12-19 8 views
-2

의 열에서 문자열 바꾸기 : 나는 위의 '문자열'의 내 열 에 나타납니다 그래서 때마다나는 다음과 같이 열에서 모든 문자열을 대체 할 SAS

strings new_strings 
ABC_MNO_S3 S1 
ABC_S1  S2 
ABC_S2  S3 
ABC_PQR_S3 S4 
XYZ_MNO_S3 S5 
XYZ_S1  S6 
XYZ_S2  S7 
XYZ_PQR_S3 S8 

'을은 말한다' 'new_string'으로 바꾸고 싶습니다. 이 목록을 배열에 넣고 TRANWRD을 사용하여 열을 검색하고 바꿀 수는 있지만 작동하지는 않습니다.

내 열 상태와 원하는 출력은 다음과 같습니다 :

states     states_result 
TR_ABC_MNO_S3_ABC_S2 TR_S1_S3 
TR_ABC_S1_ABC_S2  TR_S2_S3 
Segment     Segment 
ABC_PQR_S3    S4 
TR_XYZ_MNO_S3_XYZ_S2 TR_S5_S7 
Year     Year 
St_XYZ_S2    St_S7 

당신이 도와 주 시겠어요? 감사!

+0

귀하의 질문에 답하는 것은 가능하지만 여기에서 구체적으로 시도한 코드의 예가 포함 된 경우 더 좋을 것입니다. – Joe

+0

시도한 코드를 게시하십시오. – Reeza

답변

1

Sourav :

당신은 내가 strings 값이 states 값에 포함 찾을 수 있습니다 가정합니다 TRANWRD 언급 때문입니다. TRANWRD의 효과적인 사용의 핵심은 변수가 대상대체 인수에 사용되는 경우 값이 TRIM 인 것입니다.

교체 문제 :

  • 포함 된 하나의 목표 값 이있는 경우 TRANWRD의 단일 사용이 작동합니다.
  • 하나 이상의 대상 값이 포함될 수있는 경우 모든 대상에 대한 루프가 필요합니다.

이전 교체로 인해 이전에 분명하지 않은 유효한 교체가 발생할 수있는 가능성이 있습니다. 다음 state 값을 고려 : 모든 대상을 통해 두 번째 루프는 S2ABC_S1을 대체 할 모든 대상을 통해 첫 번째 루프가

ABC_S1 

S1ABC_MNO_S3을 교체하고 얻을 것이다

ABC_ABC_MNO_S3 

및 산출

S2 

테스트 샘플 :

data have; 
infile cards dlm="," dsd; 
length states segment year $100; 
input states segment year; 
datalines; 
"TR_ABC_MNO_S3_ABC_S2 TR_ABC_S1_ABC_S2", "ABC_PQR_S3 TR_XYZ_MNO_S3_XYZ_S2", "St_XYZ_S2" 
run; 

data mappings; 
length string $30 new_string $2; 
input string new_string; 
datalines; 
ABC_MNO_S3 S1 
ABC_S1  S2 
ABC_S2  S3 
ABC_PQR_S3 S4 
XYZ_MNO_S3 S5 
XYZ_S1  S6 
XYZ_S2  S7 
XYZ_PQR_S3 S8 
run; 

data want; 
    array maps(100,2) $50 _temporary_; * first dimension must be larger than number of mappings; 
    do _i_ = 1 by 1 until (lastmap); 
    set mappings(rename=(string=_map_from new_string=_map_to)) end=lastmap; 
    maps(_i_,1) = _map_from; 
    maps(_i_,2) = _map_to; 
    end; 

    length status $12 _result $200; 

    do until (lastdata); 

    set have end=lastdata; 
    array targets states segment year; 

status = 'ORIGINAL'; 
output; 

    do _i_ = 1 to dim(targets); 

     _result = targets[_i_]; 
     _guard = 1; 
     do until (_noreplacement or _guard >= 10); 
     _noreplacement = 1; 
     do _j_ = 1 to dim(maps,1) while(maps(_j_,1) ne ''); 
      if index(_result,trim(maps(_j_,1))) then do; 

* put _result ': ' maps(_j_,1) '-> ' maps(_j_,2); 

      _result = tranwrd(_result, trim(maps(_j_,1)), trim(maps(_j_,2))); 
      _noreplacement = 0; 
      end; 
     end; 
     end; 

     if (_guard > 10) then do; 
     put 'WARNING: Guard limit 10 reached, mappings may be cycling.' _result; 
     end; 

     targets[_i_] = _result; 
    end; 

    status = 'MAPS APPLIED'; 
    output; 
    end; 

    stop; 
    drop _:; 
run; 
+0

코드에서 공백 결과가 나타납니다. 내 데이터는 다음입니다 : 'states' 'TR_ABC_MNO_S3_ABC_S2' 'TR_ABC_S1_ABC_S2' 'Segment' 'ABC_PQR_S3' 'TR_XYZ_MNO_S3_XYZ_S2' 'Year' 는'St_XYZ_S2' – souravsarkar59

+0

당신은 원래의 질문을 편집하고 추가 할 수 코드 블록의 데이터 정보? 댓글은 3 개의 열이있는 것처럼 보입니다. – Richard

+0

단 하나의 열이 있습니다. 질의를 수정하여 샘플 열과 원하는 출력을 추가했습니다. – souravsarkar59