Создание переменной на основе данных в предопределенных векторах и дискретных результатов - PullRequest
2 голосов
/ 14 мая 2019

Предположим, респонденту (id) предлагается сделать двоичный (дискретный) выбор, выберите 1 или 2 в пяти заданиях (t = 1,2,3,4,5) (набор данных панели с пятью наблюдениями на респондента).).

Если респондент выбирает вариант 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).То есть, если выбор 2 выбран впервые в Treat1, выберите первое значение из последовательности Treat1;если во 2-й раз выбирается вариант 2 в Treat1, выберите второе значение из последовательности 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 |
|  . | . |         . |      . |       . |
|  . | . |         . |      . |       . |
|  . | . |         . |      . |       . |
|  . | . |         . |      . |       . |
|  . | . |         . |      . |       . |
+----+---+-----------+--------+---------+

Поскольку мои данные содержат тысячи наблюдений, мне было интересно, как бы был эффективен способ генерации переменной output ,

Переменные id , t , обработки и выбор доступны в моем наборе данных.

Любые мысли приветствуются.Спасибо.

Ответы [ 2 ]

3 голосов
/ 15 мая 2019

Другой возможный подход состоит в том, чтобы организовать обработку в data.table, а затем выполнить объединение и обновить по ссылке, если выбор = 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]
1 голос
/ 14 мая 2019

Вы не предоставили никаких образцов данных, поэтому сначала я создаю некоторые поддельные данные

Данные

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.

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).Затем вы перебираете task, treatment и choice, чтобы выбрать либо 30 (для choice == 1), либо используете правильное значение поиска из l

Обновление

Принимая во внимание комментарий, нам нужно сначала создать переменную task_new, которая будет содержать правильную позицию.То есть первое choice == 2 должно дать 1, второе 2 и так далее.Таким образом, мы group_by id и добавляем счетчик через cumsum.Мы используем task_new в вызове mutate после разгруппировки данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...