【问题标题】:SPSS/macro: split string into multiple variablesSPSS/macro:将字符串拆分为多个变量
【发布时间】:2021-07-26 09:26:32
【问题描述】:

我正在尝试将一个字符串变量拆分为多个虚拟编码变量。我使用这些资源来了解如何在 SPSS 中完成这项任务:

但是当我尝试使第一个适应我的需要或尝试将第二个转换为宏时,我失败了。

在我的数据集中,我有(多个)变量,其中包含一个逗号分隔的字符串,表示所选项目的不同组合(以及缺失值)。对于特定变量的每个项目,我想创建一个虚拟变量。如果该项目被选中,它应该在新的虚拟变量中用 1 表示。如果未选择,则该情况应以 0 表示。 不同的输入变量可以包含不同数量的项目。

例如:

ID VAR1 VAR2 DMMY1_1 DMMY1_2 DMMY1_3
1 1, 2 8 1 1 0
2 1 1, 3 1 0 0
3 3, 1 2, 3, 1 1 0 1
4 2, 8 0 0 0

这是我到目前为止想出的......


* DEFINE DATA. 

DATA LIST /ID 1 (F) VAR1 2-5 (A) VAR2 6-12 (A).
BEGIN DATA
11, 28
21   1, 3
33, 12, 3, 1
4    2, 8
END DATA.

* MACRO SYNTAX.

* DEFINE VARIABLES (in the long run these should/will be inside the macro function, but for now I will leave them outside).
NUMERIC v1 TO v3 (F1).
VECTOR v = v1 TO v3.
STRING #char (A1).

DEFINE split_var(vr = TOKENS(1)).
    !DO !#pos=1 !TO char.length(!vr).
        COMPUTE #char = char.substr(!vr, !#pos, 1).
        !IF (!#char !NE "," !AND !#char !NE " ") !THEN
            COMPUTE v(NUMBER(!#char, F1)) = 1.
        !IFEND.        
    !DOEND.
!ENDDEFINE.

split_var vr=VAR1.
EXECUTE.

由于我遇到的错误数不胜数,因此很难缩小我的问题范围。但我认为这个问题与我使用char.length() 函数的方式有关(我对何时使用bang 运算符有点困惑)。

如果有人有一些见解,我真的很感激一些帮助:)

【问题讨论】:

  • 您示例中的虚拟变量似乎与您的任何一个原始分隔文本变量都不对应。

标签: macros spss


【解决方案1】:

关于 SPSS 宏有一个基本问题需要了解 - 宏不会读取数据或以任何方式与数据交互。宏所做的只是操纵文本来编写语法。创建的语法稍后将在您运行时处理实际数据。
因此,例如,您的第一个错误是在语法中使用char.length(!vr)。您正试图让宏读取数据、计算长度和使用,但这根本无法完成 - 宏只能与您提供的内容一起使用。 您的代码中的另一个示例:您计算#char,然后尝试在宏中将其用作!#char。所以这显然行不通。 ! 仅位于宏函数或参数之前。 #char,在您的代码中,两者都不是,而且它不能成为一个 - 无法将数据读入宏...

给你一个小小的推动:我知道你希望宏循环为每个变量运行不同的次数,但你不能使用 char.length(!vr)。我建议尽可能多地使用宏循环,以确保您可以处理需要处理的最长变量。

还有另一个通用的策略提示——首先,创建语法来处理一个特定的变量和一个特定的分隔符。一旦成功,开始处理宏,记住宏的唯一目的是重新创建相同的工作语法,只更改变量名和分隔符的参数。

【讨论】:

  • 感谢您的提示。这是真的,作为一个 R 用户,我真的不明白宏观的东西(我在 SAS 中遇到了同样的问题)。我想这根本不是一个真正的功能。但它帮助你指出了差异:) 虽然我从(工作)非宏语法开始,然后尝试将其转换为宏,但我会用这个新视角再试一次:D
  • 请记住不要像宏中那样对需要重复的语法进行强硬。例如,您有一个 if 命令,其语法中只有变量名称应该更改 - 该命令的所有其余部分都是常规语法 - 没有理由尝试将其转换为宏 !if - !then 命令。
  • 在开发宏时,使用set mexpand=on.set mprint=on 并在输出中显示命令——这些将让您看到宏正在创建的实际语法并找出其中的任何问题。这也将有助于区分宏定义中的错误(例如使用!#char - 一个未定义的宏参数)和宏创建的语法中的错误。
【解决方案2】:

随着我对 SPSS 宏逻辑的新理解(感谢 @eli-k),问题很容易解决。这是可行的解决方案。

* DEFINE DATA. 

DATA LIST /ID 1 (F) VAR1 2-5 (A) VAR2 6-12 (A).
BEGIN DATA
11, 28
21   1, 3
33, 12, 3, 1
4    2, 8
END DATA.

* DEFINE MACRO.
DEFINE @split_var(src_var = !TOKENS(1) 
                        /dmmy_var_label = !DEFAULT(dmmy) !TOKENS(1)
                        /dmmy_var_lvls = !TOKENS(1))
    NUMERIC !CONCAT(!dmmy_var_label,1) TO !CONCAT(!dmmy_var_label, !dmmy_var_lvls) (F1).
    VECTOR #dmmy_vec = !CONCAT(!dmmy_var_label,1) TO !CONCAT(!dmmy_var_label, !dmmy_var_lvls).
    STRING #char (A1).
    LOOP #pos=1 TO char.length(!src_var).
        COMPUTE #char = char.substr(!src_var, #pos, 1).
        DO IF (#char NE "," AND #char NE " ").
            COMPUTE #index = NUMBER(#char, F1).
            COMPUTE #dmmy_vec(#index) = 1.
        END IF.
    END LOOP.
    RECODE  !CONCAT(!dmmy_var_label,1) TO !CONCAT(!dmmy_var_label, !dmmy_var_lvls) (SYSMIS=0) (ELSE=COPY).
    EXECUTE.
!ENDDEFINE.

* CALL MACRO.
@split_var src_var=VAR2 dmmy_var_lvls=8.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-30
    • 2016-02-02
    • 2015-12-19
    • 2020-09-12
    • 1970-01-01
    • 2019-02-05
    相关资源
    最近更新 更多