【问题标题】:SAS: Avoid end-of-line problem and LOST CARDSAS:避免终端问题和丢失卡
【发布时间】:2019-10-16 18:52:52
【问题描述】:

我正在完成一项 SAS 练习,其中包含以下格式的数据:

3496 Jerry         Nelson        13960 Wilson Dr.         San Diego                     CA   92191  40   4
3498 Scott         Mason         9226 College Dr.         Oak View                      CA   93022  95   2
3498                                                                                    CA          35   3
3498                                                                                    CA          35   11
3500 Michele       Stone         8393 West Ct.            Emeryville                    CA   94608  55   5
3500                                                                                    CA          70   5

对于每个人,数据会一直持续到下一个人的姓名。我认为以下代码非常接近我的需要:

libname Ch4data '\\Client\C$\Users\m210028\Google Drive\Adrian\Self-Study\SAS\Chapter4_data';

Data Ch4data.my_donations;
    Infile '\\Client\C$\Users\m210028\Google Drive\Adrian\Self-Study\SAS\Chapter4_data\Donations.dat' MISSOVER;
    Array   amounts(10);
    Array   months(10);
    Input   first_name      $  6 -  19 
            last_name       $ 20 -  33
            street_address  $ 34 -  58
            city            $ 59 -  88
            state_code      $ 89 -  93
            zip_code        $ 94 - 100
            amounts(1)       101 - 105 @ 106 
            months(1);
    end = end1;
    If ~(end1) Then
    Do;
        Input   test_char $ 6-6 @;
        i = 2;
        Do While (0 = ANYALPHA(test_char));
            Input   amounts(i)   101 - 105 @ 106 
                    months(i);
            end = end1;
            If ~(end1) Then Input test_char $ 6-6 @;
            Else test_char = '';
            i = i+1;
        End; 
    End;
Run;

Proc Print Data = Ch4data.my_donations;
    Title 'Donations to Coastal Humane Society';
Run;

问题是我在日志中收到一张 LOST CARD 注释,而文件中的姓氏 Michele Stone 没有进入数据集。我怀疑我用于检测文件结尾的代码不正确。有人可以告诉我如何检测文件结尾吗? SAS 文档没有帮助。

非常感谢您的宝贵时间!

[更新]:感谢汤姆的评论,我现在可以使用以下代码获得最后一行:

libname Ch4data '\\Client\C$\Users\m210028\Google Drive\Adrian\Self-Study\SAS\Chapter4_data';

Data Ch4data.my_donations;
    Infile '\\Client\C$\Users\m210028\Google Drive\Adrian\Self-Study\SAS\Chapter4_data\Donations.dat' MISSOVER END=end1;
    Array   amounts(10);
    Array   months(10);
    Input   first_name      $  6 -  19 
            last_name       $ 20 -  33
            street_address  $ 34 -  58
            city            $ 59 -  88
            state_code      $ 89 -  93
            zip_code        $ 94 - 100
            amounts(1)       101 - 105 @ 106 
            months(1);
    If ~(end1) Then
    Do;
        Input   test_char $ 6-6 @;
        i = 2;
        Do While (0 = ANYALPHA(test_char));
            Input   amounts(i)   101 - 105 @ 106 
                    months(i);
            If ~(end1) Then Input test_char $ 6-6 @;
            Else test_char = '';
            i = i+1;
        End; 
    End;
Run;

Proc Print Data = Ch4data.my_donations;
    Title 'Donations to Coastal Humane Society';
Run;

不幸的是,它没有排到倒数第二行。就此而言,它跳过了很多第一行记录。想法?

【问题讨论】:

  • 您的 INFILE 语句中没有包含 END= 选项。
  • 啊,我明白了。好吧,这让我得到了最后一行,但现在我没有得到倒数第二行!即将更新代码。

标签: sas


【解决方案1】:

您正在尝试将阅读和转置结合起来。首先阅读然后转置可能更容易。事实上,你可以阅读

data step1;
    Infile example truncover ;
    Input   first_name      $  6 -  19 
            last_name       $ 20 -  33
            street_address  $ 34 -  58
            city            $ 59 -  88
            state_code      $ 89 -  93
            zip_code        $ 94 - 100
            amount           101 - 105 
            month            105 - 110
    ;
    if not missing(first_name) then case+1;
run;

然后应用名称等的结转。

data step2;
  update step1(obs=0) step1;
  by case;
  output;
run;

然后转置。

data want;
   do row=1 by 1 until(last.case);
     set step2;
     by case;
     array months [10];
     array amounts [10];
     months[row]=month;
     amounts[row]=amount;
  end;
  drop row amount month;
run;

【讨论】:

  • 应该存在月份数据吗?我只看到空白列。
  • 适用于您发布的数据。确保使用 TRUNCOVER 而不是(旧的不太有用的)MISSOVER 选项。
【解决方案2】:

当您的名称检查检测到下一组的第一行时,您将需要使用行保持说明符 @@ 来保持行。

filename exercise 'c:\temp\exercise.txt';

* create file to read in;    
data _null_;
  file exercise; 
  input;
  put _infile_;
datalines;
3496 Jerry         Nelson        13960 Wilson Dr.         San Diego                     CA   92191  40   4
3498 Scott         Mason         9226 College Dr.         Oak View                      CA   93022  95   2
3498                                                                                    CA          35   3
3498                                                                                    CA          35   11
3500 Michele       Stone         8393 West Ct.            Emeryville                    CA   94608  55   5
3500                                                                                    CA          70   5
run;

* read-in the data;
* error will occur if data file has a group with more than 10 months of data;
data want;
    infile exercise end=end_of_data ;

    array   amounts(10);
    array   months(10);

    input   first_name      $  6 -  19 
            last_name       $ 20 -  33
            street_address  $ 34 -  58
            city            $ 59 -  88
            state_code      $ 89 -  93
            zip_code        $ 94 - 100
            amounts(1)       101 - 105 
@ 106       months(1);

    do i = 2 by 1 while (not end_of_data);
      input name_check $ 6-6 @@;
      if name_check = ' ' then 
        input amounts(i) 101-105 @106 months(i);
      else
        leave;  /* jump out of loop
                 * when control returns to top the input will be of the held line
                 */
    end;
run;

【讨论】:

    猜你喜欢
    • 2014-10-20
    • 2015-06-06
    • 1970-01-01
    • 2018-10-26
    • 1970-01-01
    • 2011-06-12
    • 2021-01-28
    • 2014-03-18
    • 1970-01-01
    相关资源
    最近更新 更多