【问题标题】:Reading space delimited text file into SAS将空格分隔的文本文件读入 SAS
【发布时间】:2021-02-26 11:55:28
【问题描述】:

我有以下 .txt 文件:

Mark1[Country1]
type1=1 type2=5 
type1=1.50 EUR type2=21.00 EUR 
Mark2[Country2]
type1=2 type2=1 type3=1 
type1=197.50 EUR type2=201.00 EUR type3= 312.50 EUR
....

我正在尝试将其输入到我的 SAS 程序中,以使其看起来像这样:

  Mark  Country   Type  Count   Price

1 Mark1 Country1  type1   1     1.50 
2 Mark1 Country1  type2   5     21.00 
3 Mark1 Country1  type3   NA     NA 
4 Mark2 Country2  type1   2     197.50 
5 Mark2 Country2  type2   2     201.00 
6 Mark2 Country2  type3   1     312.50 

或者可能是其他东西,但我需要它能够打印两种方式的报告

       Country1   Country2 
Type1    ...        ...  
Type2    ...        ...   
Type3    ...        ...  

但问题是如何读取那种txt文件:

  1. 读取 Mark1[Country1] 并将其分隔为两列 Mark 和 Country;
  2. 保留 Mark 和 Country 并读取每种类型的信息(+不知何故忽略 type1=,可能使用格式)并将其输入到表格中。 也许有一种方法可以使用某种输入模板来实现该或嵌套查询。

【问题讨论】:

  • 所以有时等号后有一个单词 (type1=1),而其他单词则更多 (type1=1.50 EUR)。当您拥有一种类型的字符串和拥有另一种类型的字符串时,是否有任何模式?你总是每组三行吗?
  • @Tom 是的,每组正好三行。第一个是标记和国家,第二个是每种类型的数量,第三行是价格。

标签: input sas txt


【解决方案1】:

您可以在 INFILE 语句中使用 DLM= 选项指定变量的名称。这样您就可以根据所读取的行类型更改分隔符。

看起来你每组有三行。第一个具有 MARK 和 COUNTRY 值。第二个有一个 COUNT 值列表,第三个有一个 PRICE 值列表。所以这样的事情应该可以工作。

data want ;
  length dlm $2 ;
  length Mark $8 Country $20 rectype $8 recno 8 type $10 value1 8 value2 $8 ;
  infile cards dlm=dlm truncover ;
  dlm='[]';
  input mark country ;
  dlm='= ';
  do rectype='Count','Price';
    do recno=1 by 1 until(type=' ');
      input type value1 @;
      if rectype='Price' then input value2 @;
      if type ne ' ' then output;
    end;
    input;
  end;
cards;
Mark1[Country1]
type1=1 type2=5 
type1=1.50 EUR type2=21.00 EUR 
Mark2[Country2]
type1=2 type2=1 type3=1 
type1=197.50 EUR type2=201.00 EUR type3= 312.50 EUR
;

结果:

Obs    Mark     Country     rectype    recno    type     value1    value2

  1    Mark1    Country1     Count       1      type1       1.0
  2    Mark1    Country1     Count       2      type2       5.0
  3    Mark1    Country1     Price       1      type1       1.5     EUR
  4    Mark1    Country1     Price       2      type2      21.0     EUR
  5    Mark2    Country2     Count       1      type1       2.0
  6    Mark2    Country2     Count       2      type2       1.0
  7    Mark2    Country2     Count       3      type3       1.0
  8    Mark2    Country2     Price       1      type1     197.5     EUR
  9    Mark2    Country2     Price       2      type2     201.0     EUR
 10    Mark2    Country2     Price       3      type3     312.5     EUR

【讨论】:

    【解决方案2】:

    您有 3 个名称/值对,但这些对被分成两行。需要创造性输入的不寻常的文本文件。 INPUT 语句具有行控制功能 # 以读取隐式 DATA Step 循环中的相关未来行。

    示例(过程报告)

    从当前行(相对行#1)读取markcountry,使用#2 从相对行#2 读取counts,从相对行#3 读取prices。在为给定的markcountry 进行名称/值输入后,执行基于数组的透视,一次将两个变量(countprice)转置为分类(type)数据表单。

    Proc REPORT 生成一个“双向”列表。该列表实际上是一个摘要报告(计数和价格下的单元格是默认的 SUM 聚合),但每个单元格只有一个贡献值,因此 SUM 是原始的单个值。

    data have(keep=Mark Country Type Count Price);
      attrib mark country length=$10;
    
      infile cards delimiter='[ ]' missover; 
    
      input mark country;
    
      input #2 @'type1=' count_1 @'type2=' count_2 @'type3=' count_3;
      input #3 @'type1=' price_1 @'type2=' price_2 @'type3=' price_3;
    
      array counts count_:;
      array prices price_:;
    
      do _i_ = 1 to dim(counts);
        Type = cats('type',_i_);
        Count = counts(_i_);
        Price = prices(_i_);
        output;
      end;
    datalines;
    Mark1[Country1]
    type1=1 type2=5 
    type1=1.50 EUR type2=21.00 EUR
    Mark2[Country2]
    type1=2 type2=1 type3=1 
    type1=197.50 EUR type2=201.00 EUR type3= 312.50 EUR
    ;
    
    ods html file='twoway.html';
    
    proc report data=have;
      column type country,(count price);
      define type / group;
      define country / ' ' across;
    run;
    
    ods html close;
    

    输出图像

    组合聚合

    proc means nway data=have noprint;
      class type country;
      var count price;
      output out=stats max(price)=price_max sum(count)=count_sum;
    run;
    
    data cells;
      set stats;
      if not missing(price_max) then 
        cell = cats(price_max,'(',count_sum,')');
    run;
    
    proc transpose data=cells out=twoway(drop=_name_);
      by type;
      id country;
      var cell;
    run;
    
    proc print noobs data=twoway;
    run;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-22
      • 1970-01-01
      • 2010-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多