数据清理:处理额外的if语句与执行额外的分配

时间:2013-09-18 17:13:37

标签: sas

编辑:我明白为什么这是错误的解决方法(我忘记了过去是怎么做过的)并接受了Joe的回答。如果有人对SAS中的性能考虑因素进行了更多if语句与执行额外分配的比较,我仍然会感兴趣。


首选哪种方法?

通过将多个变体/拼写错误组合到一个正确的值中来清理某些数据时, 我能做到这一点:

选项A:

if value in (
    'A: Wrong Value 1'
    'A: Typo 1'
    'a: Typo 2'
    'A: Wrong Value 2'
  ) then value = 'A: Correct Value';
else if value in (
    'B: Wrong Value 1'
    'B: Wrong Value 2'
    'B: Typo 1'
  ) then value = 'B: Correct Value';
else if value in (
    'C: Wrong Value 1'
    'C: Wrong Value 2'
    'C: Wrong Value 3'
    'C: Typo 1'
  ) then value = 'C: Correct Value';
**etc.  Assume there are a bunch of similar statements;
**with any number of items on the "in" list;

我在这些操作中看到的问题是,每次遇到“A:正确值”时,您都必须通过每个if语句处理它。这不是什么大不了的事,但是我感到不对的是,“A”组的某些东西仍然会通过所有测试运行到“Z”组。

相反,我可以写下来:

选项B

if value in (
    'A: Correct Value'
    'A: Wrong Value 1'
    'A: Typo 1'
    'a: Typo 2'
    'A: Wrong Value 2'
  ) then value = 'A: Correct Value';
else if value in (
    'B: Correct Value'
    'B: Wrong Value 1'
    'B: Wrong Value 2'
    'B: Typo 1'
  ) then value = 'B: Correct Value';
else if value in (
    'C: Correct Value'
    'C: Wrong Value 1'
    'C: Wrong Value 2'
    'C: Wrong Value 3'
    'C: Typo 1'
  ) then value = 'C: Correct Value';

这可以阻止它评估过去正确的组(并且还有一个额外的好处,即允许你在最后添加else value = 'Not Cleaned';之类的东西)。

但是,此版本最终会相当于if value = 'A: Correct Value' then value = 'A: Correct Value';。这似乎是一种浪费的操作,尽管它可能比继续检查if语句更少浪费。

到目前为止,我有:

  • 选项A
    • 优点:
      • 更短的代码
      • 仅重新分配不正确的值(无if a = 1 then a = 1
    • 缺点:
      • 如果不需要清除某个值,则必须继续执行每个if语句
      • 无法使用else子句
      • 完成
  • 选项B
    • 优点:
      • 对于干净和不干净的值,评估在右侧组停止。
      • 可以使用else子句来捕获所有未清除的值(如果您更新基础数据并希望对新值执行其他操作,则会很有帮助)
      • “in”列表包含映射到单个clean值的所有值(如果以编程方式生成这些值,可能会有帮助)
    • 缺点:
      • 您必须执行if a = 1 then a = 1操作;
      • 稍微长一点的代码,因为你必须写出两次正确的值。

我对此的想法是选项B是实现这一目标的更好方法。有权访问else语句并且不必向Z发送一个干净的“A:正确值”一直到Z语句的if语句似乎超过了避免if a = 1 then a = 1构造的任何值。但是我并不十分熟悉SAS所做的基础活动,因此重新分配操作可能比检查一些额外的if语句更耗时。

1 个答案:

答案 0 :(得分:2)

这些选项都不是数据清理的特别好的选择。壁纸编码,即生成大量IF语句,效率极低,难以阅读/维护,写入速度慢。它还将数据存储在程序中,这是不合需要的;良好的编程习惯将数据与代码分开,这样,如果数据发生变化,您只需修改(其他)数据而不是修改程序。

单值数据清理(即检查)最好使用格式。如果您愿意,可以在程序中编写一种格式,但更好的方法是在数据集(或Excel工作表或数据库表或其他任何内容)中保留该格式。

一种简单的格式解决方案:

proc format;
value q01f
1-5  = [F1.0]
other= INVALID;
quit;

data test;
input x;
x_fixed = put(x,q01f.);
if put(x,Q01f.)='INVALID' then ; *take action here;
put x= x_fixed=;
datalines;
1
2
3
6
8
5
4
1
;;;;
run;

在那里,值1到5是“合法的”,其他值被编码为“无效”。你可以使用它来代替你的IF语句列表 - 如果它是合法的,你可以获得'合法'值。当然你可以把所需的东西放在'INVALID'上;如果你想让99成为'无效'的答案,那就把99放在那里。

这不仅非常快(比多个IF语句或布尔值更快),但它易于维护。将这些合法值和格式名称放在excel文件中。您不仅可以获得易于维护的合法值列表(可以由非程序员维护),而且您可以免费获得数据字典。