【问题标题】:Creating a variable based on data in predefined vectors and discrete outcomes根据预定义向量中的数据和离散结果创建变量
【发布时间】:2019-05-14 08:06:30
【问题描述】:

假设受访者 (id) 被要求做出二元(离散)选择,在五个任务 (t=1,2,3,4,5) 中选择 1 或 2(每个受访者有五个观察值的面板数据集)。

如果受访者选择选项 1,则结果是一个固定值(假设总是 30),但如果受访者选择选项 2,则结果是不同的,取决于受访者所接受的治疗(只有一个每个受访者的治疗,因为受访者仅被随机分配到一种治疗)。假设有四种治疗(一个向量),并且在每种治疗中,如果选择了选项 2,则有五个结果。

也就是说,

treat1= 1,2,3,4,5

treat2= 6,7,8,9,10

treat3= 11,12,13,14,15

treat4= 16,17,18,19,20

例如,在 treat1 的情况下,如果第一个任务中的受访者选择选项 2,则结果等于 1。在第二个任务中,受访者选择选项 1,则结果是30(一如既往)。在第三个任务中,如果受访者选择选项 2,则结果为 2(而不是 3)。即如果第一次在treat1中选择了选项2,则从treat1序列中选择第一个值;如果在treat1 中第二次选择了选项2,则从treat 2 序列中选择第二个值,依此类推。

结果如下所示。

+----+---+-----------+--------+---------+
| id | t | treatment | choice | outcome |
+----+---+-----------+--------+---------+
|  1 | 1 |         1 |      2 |       1 |
|  1 | 2 |         1 |      1 |      30 |
|  1 | 3 |         1 |      2 |       2 |
|  1 | 4 |         1 |      1 |      30 |
|  1 | 5 |         1 |      2 |       3 |
|  2 | 1 |         3 |      1 |      30 |
|  2 | 2 |         3 |      2 |      11 |
|  2 | 3 |         3 |      2 |      12 |
|  2 | 4 |         3 |      1 |      30 |
|  2 | 5 |         3 |      2 |      13 |
|  3 | 1 |         2 |      2 |       6 |
|  3 | 2 |         2 |      1 |      30 |
|  3 | 3 |         2 |      1 |      30 |
|  3 | 4 |         2 |      1 |      30 |
|  3 | 5 |         2 |      2 |       7 |
|  4 | 1 |         4 |      1 |      30 |
|  4 | 2 |         4 |      1 |      30 |
|  4 | 3 |         4 |      1 |      30 |
|  4 | 4 |         4 |      2 |      16 |
|  4 | 5 |         4 |      1 |      30 |
|  5 | 1 |         2 |      1 |      30 |
|  5 | 2 |         2 |      1 |      30 |
|  5 | 3 |         2 |      1 |      30 |
|  5 | 4 |         2 |      1 |      30 |
|  5 | 5 |         2 |      2 |       6 |
|  . | . |         . |      . |       . |
|  . | . |         . |      . |       . |
|  . | . |         . |      . |       . |
|  . | . |         . |      . |       . |
|  . | . |         . |      . |       . |
+----+---+-----------+--------+---------+

由于我的数据有数千个观察值,我想知道什么是生成变量结果的有效方法。

idttreatmentchoice 变量在我的数据集中可用。

任何想法将不胜感激。谢谢。

【问题讨论】:

  • 要正确回答您的问题,我们需要更多详细信息。您能否更新数据并显示id == 2 的预期结果? treatment 会一直为 1 吗?等
  • @markus,感谢您的评论。我已经更新了预期的结果。治疗并不总是 1。它可能是 1 或 2 或 3 或 4。并且受访者只会被分配到四种治疗中的一种。
  • @NelsonGon,我已经检查了您提到的问题,但我相信我的问题与此完全不同。也许,我可能是错的。
  • 已撤回。由于没有样本数据,目前尚不清楚。我的错!请使用dput提供样本数据。
  • @NelsonGon,我掌握了 dput。 @thothal 使用以下代码 set.seed(1) treat_lkp <- list(trt1 = 1:5, trt2 = 6:10, trt3 = 11:15, trt4 = 16:20) d_in <- expand.grid(task = 1:5, id = 1:5) d_in$treatment <- paste0("trt", d_in$id %% 4 + 1) d_in$choice <- sample(2, NROW(d_in), TRUE) 生成了示例数据

标签: r dplyr data.table


【解决方案1】:

另一种可能的方法是将处理组织到一个data.table中,然后在choice=2时通过引用进行连接和更新

#the sequence of treatment when choice==2
DT[choice==2, ri := rowid(id)]

#look up treatment for the sequence
DT[choice==2, outcome := treat[.SD, on=.(treatment, ri), val]]

#set outcome to 30 for choice=1
DT[choice==1, outcome := 30]

#delete column
DT[, ri := NULL]

数据:

library(data.table)
treat <- data.table(treatment=rep(1:4, each=5),
    ri=rep(1:5, times=4),
    val=1:20)

DT <- fread("id,t,treatment,choice,outcome
1,1,1,2,1
1,2,1,1,30
1,3,1,2,2
1,4,1,1,30
1,5,1,2,3")
DT[, outcome := NULL]

【讨论】:

    【解决方案2】:

    你没有提供任何样本数据,所以我先创建一些假数据

    数据

    set.seed(1)
    treat_lkp <- list(trt1 = 1:5, trt2 = 6:10, trt3 = 11:15, trt4 = 16:20)
    d_in <- expand.grid(task = 1:5, id = 1:5)
    d_in$treatment <- paste0("trt", d_in$id %% 4 + 1)
    d_in$choice <- sample(2, NROW(d_in), TRUE)
    

    tidyverse 解决方案

    我使用简单的tidyverse 解决方案。

    library(purrr)
    library(dplyr)
    d_out <- d_in %>% 
      group_by(id) %>%
      mutate(task_new = cumsum(choice == 2)) %>%
      ungroup() %>%
      mutate(outcome = {
         l <- treat_lkp[as.character(d_in$treatment)]
         pmap_dbl(list(task = task_new, choice = choice, set = l),
                  function(task, choice, set)
                     ifelse(choice == 1, 30, set[task])  
                  )}
      )
    
    head(d_out)
    # # A tibble: 6 x 6
    #    task    id treatment choice task_new outcome
    #   <int> <int> <chr>      <int>    <int>   <dbl>
    # 1     1     1 trt2           1        0      30
    # 2     2     1 trt2           1        0      30
    # 3     3     1 trt2           2        1       6
    # 4     4     1 trt2           2        2       7
    # 5     5     1 trt2           1        2      30
    # 6     1     2 trt3           2        1      11
    

    说明

    您首先创建一个列表l,其中包含与您的结果相关的查找值(取决于treatment)。然后循环tasktreatmentchoice 以选择30(对于choice == 1)或者使用来自l 的正确查找值

    更新

    考虑到注释,我们现在首先需要创建一个保持正确位置的task_new 变量。那是第一个choice == 2 应该导致1 第二个2 等等。所以我们group_byid 并通过cumsum 添加计数器。取消分组数据后,我们在 mutate 调用中使用 task_new

    【讨论】:

    • 非常感谢您的解释(并生成示例数据)。在您的输出中,如果看观察#3和#4,则分别选用选项2时分别为8和9。但是,我想要的值是 6 和 7(而不是 8 和 9)。也许,我误解了你的意思。
    • 我误解了这个问题。在我的更新中修复了它。
    猜你喜欢
    • 2015-04-12
    • 1970-01-01
    • 2020-11-24
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 2021-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多