【问题标题】:SAS Transpose Comma Separated FieldSAS 转置逗号分隔字段
【发布时间】:2015-02-06 23:12:21
【问题描述】:

这是我之前的问题的后续。 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;

所以,这是我正在尝试但似乎不起作用的过程。 首先,我创建了一个插补所需的 STATES 列表,以及所述状态的计数。

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;

提前感谢您的帮助!

【问题讨论】:

    标签: sas


    【解决方案1】:

    看起来你快到了。在最后一个数据步骤中尝试此操作。

    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;
    

    【讨论】:

    • 感谢 DomPazz。这并不能完全解决长度问题,因为 ID 789 缺少 SC、TX。有没有办法强制数据语句将宏的整个长度读入x_main?
    • 重新定义STATE的长度。 data x_main; format STATE $<big number here>.;set main;...run;一般看到截断是因为变量的长度不够长。
    • 如果是因为他们处于 STATE 而不是 OUT_STATE,请尝试out_state = trim(scan(...)); 删除空格。
    • 是的...试图避免在其中放入大量数字。我可以用宏语句来做到这一点。 %let length_state=%sysevalf(3*&count_states.-1); %put &count_states.; %put &length_state.;数据 x_MAIN;长度状态 $ &length_state.;设置主要;如果 STATE='ALL' 那么 STATE="&all_states.";运行;
    【解决方案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;
    

    如果您确实确实需要状态,那么老实说,我会选择大数字(=50*3,所以不是所有 大)然后添加OPTIONS COMPRESS=CHAR; 将(给予或接受)将您的CHAR 字段转换为VARCHAR(以少量的 CPU 时间为代价,但通常远远少于节省的磁盘读/写时间)。

    【讨论】:

    • 感谢您的推荐。我绝对可以将这两个步骤结合起来……我只是在调试过程中将它们分开。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-28
    • 2014-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多