根据 sas 中另一个字符变量的值重新编码字符变量中的值

recode values in a character variable based on another character variable's value in sas

jrnlfile 是一个包含期刊名称和标识符的数据集。这是前 6 个观测值:

id      journal                         issn
56201   ACTA HAEMATOLOGICA              0001-5792
94365   ACTA PHARMACOLOGICA SINICA  
10334   ACTA PHARMACOLOGICA SINICA      1671-4083
55123   ADVANCES IN ENZYME REGULATION   0065-2571
90002   AGING   
10403   AGING                           1945-4589

比较 id 94365 和 10334。这些 obs 名称相同 journal。他们需要相同的 issnissn几乎总是缺失值的obs至少有一个伙伴obs包含匹配的journal名称和正确的issn。只要这是真的,我就想重新编码缺失的 issn,以便它包含在提到相同 journal 的其他实例中看到的 issn。修改后的数据集 want 将如下所示:

id      journal                         issn
56201   ACTA HAEMATOLOGICA              0001-5792
94365   ACTA PHARMACOLOGICA SINICA      1671-4083
10334   ACTA PHARMACOLOGICA SINICA      1671-4083
55123   ADVANCES IN ENZYME REGULATION   0065-2571
90002   AGING                           1945-4589
10403   AGING                           1945-4589

我目前在数据步骤中使用 if-else 语句来填充缺少的 issn 值和 journal:

的匹配条目
data want;
    set jrnlfile;
         if journal = "ACTA PHARMACOLOGICA SINICA" then issn = "1671-4083";
    else if journal = "AGING"                      then issn = "1945-4589";
    /*continue for 7,000 other journals*/
    run;

但是jrnlfile包含50,000个obs和7,000个独特的期刊,所以这需要很多时间并且很容易出错。 让我完成了一半,但是 issn 不是数字,我无法通过简单地向其添加值来解决问题。

jrnlfilewant 的更有效和系统的方法是什么?

您可以使用保留语句。但是这段代码有一些限制。要清空日志,将设置第一个找到的 issn。期刊组必须有一个或多个issn。

proc sort data=JRNLFILE;
    by journal descending issn;
run;

data want;
    set  JRNLFILE;
    retain t_issn;
    by journal descending issn;

    if first.journal then
        do;
            if issn="" then do;
                put "ERROR: there is no issn val for group";
                stop;
            end;
            else t_issn =issn;
        end;

    if issn="" then
        do;
            issn=t_issn;
        end;
run;

例如。如果你使用这个 table:

+-------+------------------------------+-----------+
|  id   |           journal            |    issn   |
+-------+------------------------------+-----------+
| 94365 | ACTA PHARMACOLOGICA SINICA   |           |
| 10334 | ACTA PHARMACOLOGICA SINICA   | 1671-4083 |
|     1 | ACTA PHARMACOLOGICA SINICA   | A_TEST    |
|     2 | ACTA PHARMACOLOGICA SINICA   | WAS       |
|     3 | ACTA PHARMACOLOGICA SINICA   | SATRTED   |
+-------+------------------------------+-----------+

您将获得:

+-------+----------------------------+-----------+--------+
|  id   |          journal           |   issn    | t_issn |
+-------+----------------------------+-----------+--------+
|     2 | ACTA PHARMACOLOGICA SINICA | WAS       | WAS    |
|     3 | ACTA PHARMACOLOGICA SINICA | SATRTED   | WAS    |
|     1 | ACTA PHARMACOLOGICA SINICA | A_TEST    | WAS    |
| 10334 | ACTA PHARMACOLOGICA SINICA | 1671-4083 | WAS    |
| 94365 | ACTA PHARMACOLOGICA SINICA | WAS       | WAS    |
+-------+----------------------------+-----------+--------+

错误示例。 如果你使用这个 table:

+-------+------------------------------+-----------+
|  id   |           journal            |    issn   |
+-------+------------------------------+-----------+
| 56201 | ACTA HAEMATOLOGICA           | 0001-5792 |
| 94365 | ACTA PHARMACOLOGICA SINICA   |           |
+-------+------------------------------+-----------+

你会得到一个错误:

ERROR: there is no issn val for group

*t_issn 留待理解函数:))

如果数据按 JOURNAL 排序并且有效值首先出现,那么简单的 UPDATE 可能会起作用。但要注意是否有其他变量有缺失值。

data want;
  update have(obs=0) have ;
  by journal;
  output;
run;

您可以尝试将数据与 ISSN 的非缺失值合并。这只要求数据按 JOURNAL 排序。如果只存在一个唯一的非缺失值,那将非常有效。如果有多个非缺失值,那么结果就不太好。

data want ;
   merge have have(where=(not missing(issn)) keep=journal issn rename=(issn=_2));
   by journal;
   if missing(issn) then issn=_2;
   drop _2;
run;