替换sas中列中的字符串
Replace strings in a column in 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
所以每当上面的任何一个 'string' 出现在我的专栏 'states' 我想用 '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
你能帮忙吗?谢谢!
苏拉夫:
因为您提到了 TRANWRD
,所以我假设可以在 states
值中找到 strings
值。有效使用 TRANWRD
的关键是 TRIM
当变量用于 target 和 replacement 参数时的值.
更换问题:
- 如果只有一个目标值,单次使用
TRANWRD
即可
嵌入式。
- 如果可以嵌入多个目标值,则需要对所有目标进行循环。
早期的替换有可能使 rise 成为以前不明显的有效替换。考虑以下 state
值:
ABC_ABC_MNO_S3
对所有目标的第一个循环会将 ABC_MNO_S3
替换为 S1
并产生
ABC_S1
对所有目标的第二个循环会将 ABC_S1
替换为 S2
并产生
S2
测试样本:
data have;
infile cards dlm="," dsd;
length states segment year 0;
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 new_string ;
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) _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 _result 0;
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;
我想用以下内容替换列中的所有字符串:
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
所以每当上面的任何一个 'string' 出现在我的专栏 'states' 我想用 '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
你能帮忙吗?谢谢!
苏拉夫:
因为您提到了 TRANWRD
,所以我假设可以在 states
值中找到 strings
值。有效使用 TRANWRD
的关键是 TRIM
当变量用于 target 和 replacement 参数时的值.
更换问题:
- 如果只有一个目标值,单次使用
TRANWRD
即可 嵌入式。 - 如果可以嵌入多个目标值,则需要对所有目标进行循环。
早期的替换有可能使 rise 成为以前不明显的有效替换。考虑以下 state
值:
ABC_ABC_MNO_S3
对所有目标的第一个循环会将 ABC_MNO_S3
替换为 S1
并产生
ABC_S1
对所有目标的第二个循环会将 ABC_S1
替换为 S2
并产生
S2
测试样本:
data have;
infile cards dlm="," dsd;
length states segment year 0;
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 new_string ;
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) _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 _result 0;
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;