选择在 R 中的离散选择实验中选择的选项

Selecting the option chosen in a discrete-choice experiment in R

我有以下数据集,来自一个选择实验:

   ID task opt q1 q2 q3 q4 q5 q6 q7 q8
1   1    1   1  2  3  1  2  2  1  2  1
2   1    1   2  2  3  1  2  2  1  2  1
3   1    1   3  2  3  1  2  2  1  2  1
4   1    2   1  2  3  1  2  2  1  2  1
5   1    2   2  2  3  1  2  2  1  2  1
6   1    2   3  2  3  1  2  2  1  2  1
7   1    3   1  2  3  1  2  2  1  2  1
8   1    3   2  2  3  1  2  2  1  2  1
9   1    3   3  2  3  1  2  2  1  2  1
10  1    4   1  2  3  1  2  2  1  2  1
11  1    4   2  2  3  1  2  2  1  2  1
12  1    4   3  2  3  1  2  2  1  2  1
13  1    5   1  2  3  1  2  2  1  2  1
14  1    5   2  2  3  1  2  2  1  2  1
15  1    5   3  2  3  1  2  2  1  2  1
16  1    6   1  2  3  1  2  2  1  2  1
17  1    6   2  2  3  1  2  2  1  2  1
18  1    6   3  2  3  1  2  2  1  2  1
19  1    7   1  2  3  1  2  2  1  2  1
20  1    7   2  2  3  1  2  2  1  2  1
21  1    7   3  2  3  1  2  2  1  2  1
22  1    8   1  2  3  1  2  2  1  2  1
23  1    8   2  2  3  1  2  2  1  2  1
24  1    8   3  2  3  1  2  2  1  2  1

意味着个人 1 (ID) 被问了 8 个问题 (task),每个问题有 3 个选项 (opt) 她可以从中选择。其余列 (q1...q8) 反映了她在每个选择任务中选择的选项。因此,她在问题 1 中选择了选项 2,在问题 7 中再次选择了选项 2。

我希望将其变成如下所示的数据集:

   ID task opt chosen
1   1    1   1  FALSE
2   1    1   2  TRUE 
3   1    1   3  FALSE
4   1    2   1  FALSE
5   1    2   2  FALSE
6   1    2   3  TRUE 
7   1    3   1  TRUE 
8   1    3   2  FALSE
9   1    3   3  FALSE
...
22  1    8   1  TRUE
23  1    8   2  FALSE
24  1    8   3  FALSE

换句话说,如果在该特定问题中选择了该特定选项,则新列 (chosen) 反映 TRUE,否则 FALSE

我已经尝试了所有形式的 meltreshape 以及 cast 但我还是一无所获。

谢谢!

您可以先 pivot_longerq1q8,然后 filter 匹配 task 列的“q”数字。如果 value 列与 opt 列匹配,则将 chosen 列设置为 TRUE。最后删除新创建的列。

更新:感谢@Sotos 改进了答案。现在我们直接从 valueopt 的比较中设置逻辑列 chosen 而无需 if_else.

library(dplyr)
library(tidyr)

df %>% pivot_longer(q1:q8, names_to = "Q") %>% 
  filter(task == gsub("q", "", Q)) %>% 
  mutate(chosen = value == opt) %>%
  select(-Q, -value)

   ID task opt chosen
1   1    1   1  FALSE
2   1    1   2   TRUE
3   1    1   3  FALSE
4   1    2   1  FALSE
5   1    2   2  FALSE
6   1    2   3   TRUE
7   1    3   1   TRUE
8   1    3   2  FALSE
9   1    3   3  FALSE
10  1    4   1  FALSE
11  1    4   2   TRUE
12  1    4   3  FALSE
13  1    5   1  FALSE
14  1    5   2   TRUE
15  1    5   3  FALSE
16  1    6   1   TRUE
17  1    6   2  FALSE
18  1    6   3  FALSE
19  1    7   1  FALSE
20  1    7   2   TRUE
21  1    7   3  FALSE
22  1    8   1   TRUE
23  1    8   2  FALSE
24  1    8   3  FALSE

这是一个 dplyr 解决方案,其中包含 rowwise()c_across(),您甚至不需要将数据转换为长格式。

library(dplyr)

df %>%
  rowwise() %>%
  mutate(chosen = c_across(q1:q8)[task] == opt) %>%
  ungroup() %>%
  select(!q1:q8)

# A tibble: 24 × 4
      ID  task   opt chosen
   <int> <int> <int> <lgl> 
 1     1     1     1 FALSE 
 2     1     1     2 TRUE  
 3     1     1     3 FALSE 
 4     1     2     1 FALSE 
 5     1     2     2 FALSE 
 6     1     2     3 TRUE  
 7     1     3     1 TRUE  
 8     1     3     2 FALSE 
 9     1     3     3 FALSE 
10     1     4     1 FALSE 
11     1     4     2 TRUE  
12     1     4     3 FALSE 
13     1     5     1 FALSE 
14     1     5     2 TRUE  
15     1     5     3 FALSE 
16     1     6     1 TRUE  
17     1     6     2 FALSE 
18     1     6     3 FALSE 
19     1     7     1 FALSE 
20     1     7     2 TRUE  
21     1     7     3 FALSE 
22     1     8     1 TRUE  
23     1     8     2 FALSE 
24     1     8     3 FALSE