【问题标题】:SAS / Using an array to convert multiple character variables to numericSAS / 使用数组将多个字符变量转换为数值
【发布时间】:2023-03-21 08:05:01
【问题描述】:

我是 SAS 新手。我正在尝试将字符变量转换为数字。下面的代码适用于一个变量,但我需要同时转换 50 多个变量。数组能解决这个问题吗?如果是这样,我将如何编写语法?

DATA conversion_subset;
SET have;
new_var = input(oldvar,4.); 
drop oldvar; 
rename newvar=oldvar;
RUN;

@Reeza

DATA conversion_subset;
SET have;

Array old_var(*) $ a_20040102--a_20040303 a_302000--a_302202;
* The first list contains 8 variables. The second list contains 7 variables;
Array new_var(15) var1-var15;

Do i=1 to dim(old_var);
 new_var(i) = input(old_var(i),4.); 
End;

*drop a_20040102--a_20040303 a_302000--a_302202; 
*rename var1-var15 = a_20040102--a_20040303 a_302000--a_302202;
 RUN;  

注意:第 64 行第 19 列的函数 INPUT 的参数无效 (new_var(i) = 输入(old_var(i),4.)

@Reeza

我仍然停留在这个数组上。您的帮助将不胜感激。我的代码:

DATA conversion_subset (DROP= _20040101 _20040201 _20040301);
SET replace_nulls;
Array _char(*) $ _200100--_601600;
Array _num(*) var1-var90;
Do i=1 to dim(_char);
 _num(i) = input(_char(i),4.); 
End;
RUN;

我收到以下错误:错误:第 64 行第 6 列的数组下标超出范围。第 64 行包含输入语句。

【问题讨论】:

  • 数据最初是如何加载的?来自平面文件(csv、xlsx、xml)、数据库连接、datalines?如果是这样,请提供此类代码以在源头调整列类型。
  • @Reeza。我需要在 INPUT 语句中更改什么内容吗?
  • 尝试明确列出变量,看看它是否有效。

标签: arrays sas


【解决方案1】:

是的,数组解决了这个问题。您将需要一种简单的方法来列出变量,因此也要查看 SAS 变量列表。例如,如果您在 first 和 last 之间转换所有字符变量,您可以将它们列为 first_var-character-last_var。

在 SO 的其他问题中说明了重命名/删除。

DATA conversion_subset;
 SET have;
 Array old_var(50) $ first-character-last;
 Array new_var(50) var1-var50;
 Do i=1 to 50;
     new_var(i) = input(oldvar(i),4.); 
  End;
 RUN;

【讨论】:

  • Reeza,如何将多个字符变量列表合并到数组语句中?例如数组 old_var(10) $ var1-var4, var8, var15-20;
  • @Maldini 是的,不过删除逗号分隔符。
  • 请将代码/错误添加到您的问题中。我无法在 cmets 中破译它。
  • 注意:第 64 行第 19 列的函数 INPUT 参数无效。
    第 64 行:new_var(i) = input(old_var(i),4.);
  • @Maldini,这两个数组的大小必须相同,否则循环会尝试从缺少的变量进行转换,因此您的输入参数无效错误。正如@Reeza 在这里显示的那样,将变量 1 对 1 转换为具有相同大小的 old_varnew_var
【解决方案2】:

正如@Parfait 建议的那样,最好在获得它时进行调整,而不是在它已经在 SAS 数据集中之后进行调整。但是,如果您获得了数据集并且必须对其进行转换,那么这就是您必须做的事情。您可以将 WHERE 子句添加到 PROC SQL 以排除不应转换的变量。如果这样做,除非您将它们添加到 CREATE TABLE 的 SELECT 子句中,否则它们将不会出现在最终数据集中。

PROC CONTENTS DATA=have OUT=havelist NOPRINT ;
RUN ; %* get variable names ;

PROC SQL ;
  SELECT 'INPUT(' || name || ',4.) AS ' || name
    INTO :convert SEPARATED BY ','
    FROM havelist
  ; %* create the select statement ;

  CREATE TABLE conversion_subset AS
    SELECT &convert
    FROM have
  ;
QUIT ;

如果排除变量是一个问题和/或您想使用 DATA 步骤,则使用上面的 PROC CONTENTS 并遵循:

PROC SQL ;
  SELECT COMPRESS(name || '_n=INPUT(' || name || ',4.)'),
         COMPRESS(name || '_n=' || name),
         COMPRESS(name)
    INTO :convertlst SEPARATED BY ';',
         :renamelst SEPARATED BY ' ',
         :droplst SEPARATED BY ' '
    FROM havelist
  ;
QUIT ;

DATA conversion_subset (RENAME=(&renamelst)) ;
  SET have ;
  &convertlst ;
  DROP &droplst ;
RUN ;

再次,添加 where 子句以排除不应转换的变量。这将自动保留您在 PROC SQL SELECT 中使用 WHERE 从转换中排除的所有变量。

如果变量太多,或者它们的名称很长,或者在末尾添加 _n 会导致名称冲突,事情可能会变得很糟糕(宏变量的数据过多,字段名称非法,一个字段覆盖另一个字段,分别)。

【讨论】:

  • 谢谢@Ludwig。 “name”是变量名还是变量列表?
  • 我收到 2 个错误。错误 #1。错误 73-322:期待 INTO。 -->> INTO :convert SEPARATED BY ','
  • 错误 22-322:语法错误,需要以下之一:名称、带引号的字符串、数字常量、日期时间常量、缺失值、BTRIM、INPUT、PUT、SUBSTRING、USER . ----> 选择 & 转换
  • 抱歉,一直在换工作。 Name 是 havelist 中变量的名称。这些值是 have 中的变量名称。错误可能与 SELECT 子句中的额外逗号有关 - 现在已删除。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-17
  • 2014-09-22
相关资源
最近更新 更多