在R中编写SAS宏的等效项

aor9mmx1  于 2023-06-27  发布在  其他
关注(0)|答案(1)|浏览(103)

抱歉重复,但我意识到我写得很糟糕,所以这是我的第二次尝试:
我在SAS中有以下宏,我正试图将其迁移到R:

%macro recode_var(var=);
if &var in (1,2,3,4,5) then do;
    if &var = 1 then &var._r = 0;
    if &var = 2 then &var._r = 25;
    if &var = 3 then &var._r = 50;
    if &var = 4 then &var._r = 75;
    if &var = 5 then &var._r = 100;
end;
%mend;

这是由行调用的

%recode_var(var=Q7_1);

这创建了具有基于Q7_1的值的值的新变量Q7_1_r。我有100个变量来调用宏(例如Q7_5、Q15_6、Q35_4)。写R等价物的最好方法是什么?
下面是我尝试的一个可重复的示例:

Q1_1 <- c(1,2,3,4,5)
    Q1_2 <- c(5,4,5,3,2)
    Q1_3 <- c(3,4,5,1,1)

    df <- data.frame(Q1_1,Q1_2,Q1_3)

    df

    testvar <- function(var){
    newfile <- mutate(df, var||_r = case_when(var == 1 ~ 0,
                                                var == 2 ~ 25,
                                                var == 3 ~ 50,
                                                var == 4 ~ 75,
                                                var == 5 ~ 100))
    }

    testing <- testvar(df$Q1_2)
    testing <- testvar(df$Q1_3)
    testing

这将创建一个名为“var_r”的新变量,该变量的值基于输入变量的值。(例如,对于Q1_2,它给出var_r为100,75,100,50,25,而Q1_3产生50,75,100,0,0)。此新变量是数据框的一个额外列。有两件事我正在尝试做这件事,并寻求建议:
1.我希望输出变量的名字是基于输入变量的名字--取输入变量的名字,并在上面加上“_r”。代替“var_r”,如果输入变量var是Q6_1,则新变量将是Q6_1_r。我希望这适用于输入变量“var”的任何输入值,然后运行下面的代码行(testing <- testvar(df$Q1_2))来分配一个值“var”,然后它将成为新变量名称的一部分。
1.我有超过100个变量用于这个块,所以一旦我做了一次,例如。对于Q1_2,我想再次运行它,并向集合中添加另一个变量,例如。Q2_2。
因此,在上面的结尾处的输出将具有六列-
Q1_1、Q1_2、Q1_3、Q1_1_r、Q1_2_r、Q1_3_r
并根据代码输入适当的条目。如果我可以对可重现的示例这样做,那么我可以将其应用于我拥有的100个变量。我希望这是现在更清楚。有什么建议吗

sd2nnvve

sd2nnvve1#

一个简单的方法是这样的:

# amended dataset to cover additional needs:
Q1_1 <- c(1,2,3,4,5)
Q1_2 <- c(5,4,5,3,2)
Q1_3 <- c(7,6,5,1,1)
df <- data.frame(Q1_1,Q1_2,Q1_3)

library(tidyverse)

typeA <- c("Q1_1", "Q1_2")
typeB <- c("Q1_3")

df %>%
  mutate(across(all_of(typeA), # Apply the function to each column whose name matches a string in object typeA
                ~ case_when(
                  . == 1 ~ 0,
                  . == 2 ~ 25,
                  . == 3 ~ 50,
                  . == 4 ~ 75,
                  . == 5 ~ 100),
                .names = "{.col}_r")) %>% # name of new column is the old name plus "_r" 
  mutate(across(all_of(typeB), # again but for typeB
                ~ case_when(
                  . == 1 ~ 0,
                  . == 2 ~ 12.5,
                  . == 3 ~ 25,
                  . == 4 ~ 37.5,
                  . == 5 ~ 50,
                  . == 6 ~ 62.5,
                  . == 7 ~ 75,
                  . == 8 ~ 87.5,
                  . == 9 ~ 100),
                .names = "{.col}_r"))

输出:

Q1_1 Q1_2 Q1_3 Q1_1_r Q1_2_r Q1_3_r
1    1    5    7      0    100   75.0
2    2    4    6     25     75   62.5
3    3    5    5     50    100   50.0
4    4    3    1     75     50    0.0
5    5    2    1    100     25    0.0

如果你真的想让它成为一个接受变量的函数,你可以,但是如果你能制定一个定义列的select语句(例如我的starts_with("Q"),或合适标题的向量),那么这是一个简单的方法。
注意-这可能会使事情过于复杂。如果这个比例和你的例子一样,而不仅仅是一个简化的版本,那么你可以这样做:

df %>%
  mutate(across(all_of(typeA),
                ~ (.-1)*25,
                .names = "{.col}_r")) %>% 
  mutate(across(all_of(typeB), 
                ~ (.-1)*12.5,
                .names = "{.col}_r"))

编辑:更新为允许不同的答案类型块

相关问题