2

编辑:我明白为什么这是错误的做法(而且我忘记了我过去是如何做到的)并接受了乔的回答。如果有人对 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”列表包含映射到单个干净值的所有值(如果您以编程方式生成这些值可能会有所帮助)
    • 缺点:
      • 你必须if a = 1 then a = 1做手术;
      • 代码稍长,因为您必须写出两次正确的值。

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

4

1 回答 1

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 是“合法的”,而其他值被编码为“INVALID”。您可以使用它来代替您的 IF 语句列表 - 如果它在此之上是合法的,那么您将获得“合法”值。当然你可以放一些想要的东西而不是'INVALID';如果您希望 99 成为“无效”响应,则将 99 放在那里。

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

于 2013-09-18T17:51:34.040 回答