这是我早期问题的后续行动。 Transposing Comma-delimited field
我为特定情况工作的答案,但现在我有一个更大的数据集,所以在datalines语句中读取它不是一个选项。我有一个类似于此过程创建的数据集:
data MAIN;
input ID STATUS STATE $;
cards;
123 7 AL,NC,SC,NY
456 6 AL,NC
789 7 ALL
;
run;
这里有两个问题: 1:我需要为STATE列中的每个状态分别设置一行 2:注意第三个观察结果是“全部”。我需要用特定状态列表替换它,我可以从单独的数据集中获取(下面)。
data STATES;
input STATE $;
cards;
AL
NC
SC
NY
TX
;
run;
所以,这是我尝试的过程似乎不起作用。 首先,我创建了一个插补所需的状态列表,以及所述状态的计数。
proc sql;
select distinct STATE into :all_states separated by ','
from STATES;
select count(distinct STATE) into :count_states
from STATES;
quit;
其次,我尝试将该列表归于STATE的'ALL'值。这是出现第一个错误的地方。如何确保变量STATE足够长以获得新值?另外,我该如何处理逗号?
data x_MAIN;
set MAIN;
if STATE='ALL' then STATE="&all_states.";
run;
最后,我使用SCAN函数一次读取一个状态。我在这里也遇到了错误,但我认为修复上述部分可能会解决它。
data x_MAIN_mod;
set x_MAIN;
array state(&count_states.) state:;
do i=1 to dim(state);
state(i) = scan(STATE,i,',');
end;
run;
提前感谢您的帮助!
答案 0 :(得分:3)
看起来你几乎就在那里。请在最后一个数据步骤中尝试此操作。
data x_MAIN_mod;
set x_MAIN;
format out_state $2.;
nstate = countw(state,",");
do i=1 to nstate;
out_state = scan(state,i,",");
output;
end;
run;
答案 1 :(得分:2)
你真的必须有两个这样的步骤吗?如果您没有中间数据集,可以在临时变量中使用“大数字”而不会对事物产生太大影响。
data x_MAIN;
length state_temp $150;
set MAIN;
if STATE='ALL' then STATE_temp="&all_states.";
else STATE_temp=STATE;
array state(&count_states.) state:;
do i=1 to dim(state);
state(i) = scan(STATE,i,',');
end;
drop STATE_temp;
run;
如果你真的做需要STATE,那么老实说我会选择大号(= 50 * 3,所以不是所有那个大)然后添加将OPTIONS COMPRESS=CHAR;
字段转换为CHAR
VARCHAR
的{{1}} {代价为一点点CPU时间,但通常远远低于节省的磁盘读/写时间)。