选择在 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
。
我已经尝试了所有形式的 melt
和 reshape
以及 cast
但我还是一无所获。
谢谢!
您可以先 pivot_longer
列 q1
到 q8
,然后 filter
匹配 task
列的“q”数字。如果 value
列与 opt
列匹配,则将 chosen
列设置为 TRUE
。最后删除新创建的列。
更新:感谢@Sotos 改进了答案。现在我们直接从 value
与 opt
的比较中设置逻辑列 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
我有以下数据集,来自一个选择实验:
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
。
我已经尝试了所有形式的 melt
和 reshape
以及 cast
但我还是一无所获。
谢谢!
您可以先 pivot_longer
列 q1
到 q8
,然后 filter
匹配 task
列的“q”数字。如果 value
列与 opt
列匹配,则将 chosen
列设置为 TRUE
。最后删除新创建的列。
更新:感谢@Sotos 改进了答案。现在我们直接从 value
与 opt
的比较中设置逻辑列 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