在 proc-iml 中创建新数据集时如何不更改先前存在的字符变量的长度?

How to not change the length of preexisting character variables when creating a new dataset in proc-iml?

我有一个在 proc-iml 中操作的数据集,然后创建一个新数据集读取其中的一些操作值。当我读取字符值时,它们的长度从 7 变为 9。

这并没有真正造成问题,只是有点烦人,当我稍后合并这个新数据集时,我收到了两个数据集中变量长度不同的警告。

有没有办法保持原变量的长度?

示例代码

data data1;
infile datalines delimiter=',';

input classif :. time :.;
datalines;
05, 2021_11
051, 2021_11
;
run;

proc iml;
    use work.data1;
    read all var {classif time } into _temp_1;
    classif = _temp_1[,1];
    time   = _temp_1[,2];
close;
create work.data2 var{classif time};
append; 
quit;

观察data1的时间长度是7,而data2的时间长度是9。

来自Understanding the SAS/IML Language

Defining a Matrix

A matrix is the fundamental structure in the SAS/IML language. A matrix is a two-dimensional array of numeric or character values. Matrices are useful for working with data and have the following properties:

  • Matrices can be either numeric or character. Elements of a numeric matrix are double-precision values. Elements of a character matrix are character strings of equal length.

INTO将字符值放入矩阵_temp_1中,矩阵必须包含所有原始值,因此元素宽度是最宽数据集变量的属性长度。

_temp_1 矩阵元素的属性通过赋值语句传播。

正如@Richard 所解释的,当您将两个长度不同的字符变量读入公共矩阵的列时,就会发生这种情况。我可以想到至少三种解决方法。根据您的应用,其中一种方法可能比其他方法更方便。

proc iml;
/* Option 1: Read variables into vectors, not a matrix */
use work.data1;
read all var {classif time };
close;
print (nleng(time))[L="nleng(time)"];

/* Option 2: Allocate time to have LENGTH=7 and copy the data in */
use work.data1;
read all var {classif time } into _temp_1;
close;
time = j(nrow(_temp_1), 1, BlankStr(7));  /* allocate char vector */
time[,]   = _temp_1[,2];                  /* copy the data */
print (nleng(time))[L="nleng(time)"];

/* Option 3: Read into a table instead of a matrix. */
tbl = TableCreateFromDataset("work", "data1") ;
classif = TableGetVarData(tbl, {"Classif"});
time = TableGetVarData(tbl, {"time"});
print (nleng(time))[L="nleng(time)"];

如果您希望 DATA1 中的变量与 DATA2 中的变量定义相同,您可以在 PROC IML 代码之后添加一个数据步骤。

data data2;
  set data1(obs=0) data2;
run;

之所以有效,是因为 SAS 在第一次看到变量时定义了变量。在这种情况下,变量由 DATA1 中的定义方式定义,即使 OBS=0 数据集选项将阻止实际从 DATA1 读取任何观察结果。