SAS 转置逗号分隔字段
SAS Transpose Comma Separated Field
这是我之前的一个问题的后续问题。
Transposing Comma-delimited field
我得到的答案适用于特定案例,但现在我有一个更大的数据集,因此无法在数据线语句中读取它。我有一个类似于此过程创建的数据集:
data MAIN;
input ID STATUS STATE $;
cards;
123 7 AL,NC,SC,NY
456 6 AL,NC
789 7 ALL
;
run;
这里有两个问题:
1:我需要为 STATE 列中的每个状态单独一行
2:请注意第三个观察结果为 'ALL'。我需要将其替换为特定状态的列表,我可以从单独的数据集(下方)中获取该列表。
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;
其次,我尝试推算 'ALL' 值出现在 STATE 的列表中。这是出现第一个错误的地方。如何确保变量 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;
在此先感谢您的帮助!
看起来你快到了。在最后一个数据步骤上试试这个。
data x_MAIN_mod;
set x_MAIN;
format out_state .;
nstate = countw(state,",");
do i=1 to nstate;
out_state = scan(state,i,",");
output;
end;
run;
你真的必须有这样的两个步骤吗?如果你没有中间数据集,你可以在临时变量中使用 'big number' 并且不会对事物产生太大影响。
data x_MAIN;
length state_temp 0;
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;
如果你真的确实需要状态,那么老实说我会选择大数字(=50*3,所以不是所有那个 big) 然后添加 OPTIONS COMPRESS=CHAR;
这将(给予或接受)将你的 CHAR
字段变成 VARCHAR
(以一点点 CPU 时间为代价,但通常远远少于磁盘 read/write 节省的时间。
这是我之前的一个问题的后续问题。 Transposing Comma-delimited field
我得到的答案适用于特定案例,但现在我有一个更大的数据集,因此无法在数据线语句中读取它。我有一个类似于此过程创建的数据集:
data MAIN;
input ID STATUS STATE $;
cards;
123 7 AL,NC,SC,NY
456 6 AL,NC
789 7 ALL
;
run;
这里有两个问题: 1:我需要为 STATE 列中的每个状态单独一行 2:请注意第三个观察结果为 'ALL'。我需要将其替换为特定状态的列表,我可以从单独的数据集(下方)中获取该列表。
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;
其次,我尝试推算 'ALL' 值出现在 STATE 的列表中。这是出现第一个错误的地方。如何确保变量 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;
在此先感谢您的帮助!
看起来你快到了。在最后一个数据步骤上试试这个。
data x_MAIN_mod;
set x_MAIN;
format out_state .;
nstate = countw(state,",");
do i=1 to nstate;
out_state = scan(state,i,",");
output;
end;
run;
你真的必须有这样的两个步骤吗?如果你没有中间数据集,你可以在临时变量中使用 'big number' 并且不会对事物产生太大影响。
data x_MAIN;
length state_temp 0;
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;
如果你真的确实需要状态,那么老实说我会选择大数字(=50*3,所以不是所有那个 big) 然后添加 OPTIONS COMPRESS=CHAR;
这将(给予或接受)将你的 CHAR
字段变成 VARCHAR
(以一点点 CPU 时间为代价,但通常远远少于磁盘 read/write 节省的时间。