重申 R 中嵌套的 ifelse 语句

Reiterate over nested ifelse statements in R

这是我的小标题。

data_current <- structure(list(ID = c(1001, 1002, 1003, 1004, 1005), Posttest.Scenario.1.Pair = c(4, 
    1, 4, 4, 4), Posttest.Scenario.2.Pair = c(5, 4, 5, 3, 5), Posttest.Scenario.3.Pair = c(2, 
    3, 3, 5, 2), Posttest.Scenario.4.Pair = c(1, 2, 1, 1, 3), Posttest.Scenario.5.Pair = c(3, 
    5, 2, 2, 1), Posttest.Pair.1.Scenario = c("Driveway Drunk", "Driveway Drunk", 
    "Driveway Drunk", "Locked Out", "Driveway Drunk"), Posttest.Pair.2.Scenario = c("Parking Lot Duo", 
    "Parking Lot Duo", "Domestic Disturbance", "Domestic Disturbance", 
    "Domestic Disturbance"), Posttest.Pair.3.Scenario = c("Baby on Bridge", 
    "Down and Out", "Down and Out", "Baby on Bridge", "Down and Out"
    ), Posttest.Pair.4.Scenario = c("Homeless at Business", "Biker Billy", 
    "Biker Billy", "Homeless at Business", "Biker Billy"), Posttest.Pair.5.Scenario = c("NASA EDP", 
    "Misery Mountain", "Misery Mountain", "NASA EDP", "Misery Mountain"
    )), groups = structure(list(.rows = structure(list(1L, 2L, 3L, 
        4L, 5L), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", 
    "list"))), row.names = c(NA, -5L), class = c("tbl_df", "tbl", 
    "data.frame")), row.names = c(NA, -5L), class = c("rowwise_df", 
    "tbl_df", "tbl", "data.frame"))

请原谅场景名称;它们是警察训练场景的名称。有五“对”场景。在每一对中,每个参与者在前测(已完成)时随机获得一个场景,在后测时随机获得另一个场景。

名为“Posttest.Scenario.x.Pair”的列在表示的顺序位置包含对名称(即 3)。例如,如果 Posttest.Scenario.1.Pair = 4,这意味着第一个后测试场景将是来自对 #4.

的指定场景

名为“Posttest.Pair.x.Scenario”的列包含为 5 对中的每一对分配的测试后场景的名称。

我正在尝试在右侧创建额外的五列 ("Posttest.Scenario.x")。这些应包含场景的名称(而不是对标识符),按呈现顺序排列:

    data_desired <- structure(list(ID = c(1001, 1002, 1003, 1004, 1005), Posttest.Scenario.1.Pair = c(4, 
1, 4, 4, 4), Posttest.Scenario.2.Pair = c(5, 4, 5, 3, 5), Posttest.Scenario.3.Pair = c(2, 
3, 3, 5, 2), Posttest.Scenario.4.Pair = c(1, 2, 1, 1, 3), Posttest.Scenario.5.Pair = c(3, 
5, 2, 2, 1), Posttest.Pair.1.Scenario = c("Driveway Drunk", "Driveway Drunk", 
"Driveway Drunk", "Locked Out", "Driveway Drunk"), Posttest.Pair.2.Scenario = c("Parking Lot Duo", 
"Parking Lot Duo", "Domestic Disturbance", "Domestic Disturbance", 
"Domestic Disturbance"), Posttest.Pair.3.Scenario = c("Baby on Bridge", 
"Down and Out", "Down and Out", "Baby on Bridge", "Down and Out"
), Posttest.Pair.4.Scenario = c("Homeless at Business", "Biker Billy", 
"Biker Billy", "Homeless at Business", "Biker Billy"), Posttest.Pair.5.Scenario = c("NASA EDP", 
"Misery Mountain", "Misery Mountain", "NASA EDP", "Misery Mountain"
), Posttest.Scenario.1 = c("Homeless at Business", "Driveway Drunk", 
"Biker Billy", "Homeless at Business", "Biker Billy"), Posttest.Scenario.2 = c("NASA EDP", 
"Biker Billy", "Misery Mountain", "Baby on Bridge", "Misery Mountain"
), Posttest.Scenario.3 = c("Parking Lot Duo", "Down and Out", 
"Down and Out", "NASA EDP", "Domestic Disturbance"), Posttest.Scenario.4 = c("Driveway Drunk", 
"Parking Lot Duo", "Driveway Drunk", "Locked Out", "Down and Out"
), Posttest.Scenario.5 = c("Baby on Bridge", "Misery Mountain", 
"Domestic Disturbance", "Domestic Disturbance", "Driveway Drunk"
)), groups = structure(list(.rows = structure(list(1L, 2L, 3L, 
    4L, 5L), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", 
"list"))), row.names = c(NA, -5L), class = c("tbl_df", "tbl", 
"data.frame")), row.names = c(NA, -5L), class = c("rowwise_df", 
"tbl_df", "tbl", "data.frame"))

这是我写的,它完成了工作:

  rowwise() %>%
  mutate(`Posttest Scenario 1` = ifelse(Posttest.Scenario.1.Pair == 1, Posttest.Pair.1.Scenario,
                                 ifelse(Posttest.Scenario.1.Pair == 2, Posttest.Pair.2.Scenario,
                                 ifelse(Posttest.Scenario.1.Pair == 3, Posttest.Pair.3.Scenario,
                                 ifelse(Posttest.Scenario.1.Pair == 4, Posttest.Pair.4.Scenario,
                                 ifelse(Posttest.Scenario.1.Pair == 5, Posttest.Pair.5.Scenario,"NA"))))),
         `Posttest Scenario 2` = ifelse(Posttest.Scenario.2.Pair == 1, Posttest.Pair.1.Scenario,
                                 ifelse(Posttest.Scenario.2.Pair == 2, Posttest.Pair.2.Scenario,
                                 ifelse(Posttest.Scenario.2.Pair == 3, Posttest.Pair.3.Scenario,
                                 ifelse(Posttest.Scenario.2.Pair == 4, Posttest.Pair.4.Scenario,
                                 ifelse(Posttest.Scenario.2.Pair == 5, Posttest.Pair.5.Scenario,"NA"))))),
         `Posttest Scenario 3` = ifelse(Posttest.Scenario.3.Pair == 1, Posttest.Pair.1.Scenario,
                                 ifelse(Posttest.Scenario.3.Pair == 2, Posttest.Pair.2.Scenario,
                                 ifelse(Posttest.Scenario.3.Pair == 3, Posttest.Pair.3.Scenario,
                                 ifelse(Posttest.Scenario.3.Pair == 4, Posttest.Pair.4.Scenario,
                                 ifelse(Posttest.Scenario.3.Pair == 5, Posttest.Pair.5.Scenario,"NA"))))),
         `Posttest Scenario 4` = ifelse(Posttest.Scenario.4.Pair == 1, Posttest.Pair.1.Scenario,
                                 ifelse(Posttest.Scenario.4.Pair == 2, Posttest.Pair.2.Scenario,
                                 ifelse(Posttest.Scenario.4.Pair == 3, Posttest.Pair.3.Scenario,
                                 ifelse(Posttest.Scenario.4.Pair == 4, Posttest.Pair.4.Scenario,
                                 ifelse(Posttest.Scenario.4.Pair == 5, Posttest.Pair.5.Scenario,"NA"))))),
         `Posttest Scenario 5` = ifelse(Posttest.Scenario.5.Pair == 1, Posttest.Pair.1.Scenario,
                                 ifelse(Posttest.Scenario.5.Pair == 2, Posttest.Pair.2.Scenario,
                                 ifelse(Posttest.Scenario.5.Pair == 3, Posttest.Pair.3.Scenario,
                                 ifelse(Posttest.Scenario.5.Pair == 4, Posttest.Pair.4.Scenario,
                                 ifelse(Posttest.Scenario.5.Pair == 5, Posttest.Pair.5.Scenario,"NA"))))))

但我知道这很糟糕,夫妻关系会得到很大改善。我只是不知道该怎么做。它是一个使用函数的循环吗?你能帮忙吗?

也许您可以使用 case_when 并循环遍历 Posttest.Scenario.1.PairPosttest.Scenario.5.Pair

library(dplyr)

new_data <- data_current %>% mutate(across(Posttest.Scenario.1.Pair:Posttest.Scenario.5.Pair, ~ case_when(
          .x==1 ~ Posttest.Pair.1.Scenario,
          .x==2 ~ Posttest.Pair.2.Scenario,
          .x==3 ~ Posttest.Pair.3.Scenario,
          .x==4 ~ Posttest.Pair.4.Scenario,
          .x==5 ~ Posttest.Pair.5.Scenario,
          TRUE ~ NA_character_), .names = "{paste0('Posttest.Scenario.', 1:5)}"))

identical(new_data, data_desired)
[1] TRUE

一个通用的解决方案,以防您不仅有 5 个而且有更多:

d <- data_current %>%
  left_join(pivot_longer(.,-ID, names_to = '.value', names_pattern =  '(\w+)$')%>%
    group_by(ID) %>%
    transmute(value = Scenario[Pair], 
              name = paste0('Posttest.Scenario.', seq(n()))) %>%
    pivot_wider()
  )
  

我们可以测试是否相等:

all.equal(d, data_desired)
[1] TRUE