当 mutate 需要来自不同变量子集和循环的额外参数时——dplyr 和 tidyverse 应用于教育领域

When mutate needs extra arguments from different subset of variables and loops -- dplyr and tidyverse applied to educational field

假设我在三个时间点评估了一个测试分数。因此,每个参与者在 T1(基线)、T2(post-intervention)和 T3(3 个月 follow-up)都有一个单独的分数。下图显示了当前数据集。

如果第二次评估 (Post-intervention) 的结果比第一次评估(基线)少 0.5(或更多),我想添加一个新的二进制变量 (1/0),依此类推.因此,第一个参与者 (id_1 == 1) 将收到此变量的 1(因为 1.5 - 0.8 = 0.7 而 0.7 > 0.5)。同一个参与者在 3 个月时 follow-up 将收到 0,因为 0.8 - 0.5 = 0.3 而这个结果不 > 0.5。

我的问题背后的基本原理建议我使用 mutate,但是一旦结果以两个变量为条件 "loops",我就很难处理这个问题。

我想继续使用 tidyverse 环境,下面的代码使这个问题很容易重现。

谢谢

ds <-structure(list(id_1 = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 
                             5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 
                             11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 
                             17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 
                             22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 
                             27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 
                             33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 
                             38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43, 
                             43, 44, 44, 44, 45, 45, 45, 46, 46, 46, 47, 47, 47, 48, 48, 48, 
                             49, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53, 53, 54, 
                             54, 54, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
                             NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
                             NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
                             NA, NA, NA, NA, NA, NA, NA, NA), time = structure(c(1L, 2L, 3L, 
                                                                                 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
                                                                                 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 
                                                                                 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 
                                                                                 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
                                                                                 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 
                                                                                 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 
                                                                                 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
                                                                                 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 
                                                                                 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 
                                                                                 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, NA, 
                                                                                 NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
                                                                                 NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
                                                                                 NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
                                                                                 NA, NA, NA, NA, NA), .Label = c("Baseline", "Post-intervention", 
                                                                                                                 "3-month follow-up"), class = "factor"), acq_6 = c(1.5, 0.8, 
                                                                                                                                                                    0.5, 1, 0, NA, 0.5, 0.5, 0.3, 3.1, 1.5, NA, 3.1, 0.8, 1.2, 1, 
                                                                                                                                                                    0.3, 0, 3.8, 2.7, 0.3, 4, 2, NA, 0.5, 0.8, 1, 2.2, 2.1, NA, 1.5, 
                                                                                                                                                                    0.7, 0.7, 1.9, 0.5, 0.3, 3.7, 1.9, 2.5, 0.8, 1.3, 1, 2, 3.3, 
                                                                                                                                                                    3.3, 2.1, 1.6, 2.2, 2.2, 1.3, 2.3, 2, 0.5, 0.5, 1.7, 1.9, 1.5, 
                                                                                                                                                                    1.8, 1.4, NA, 2.9, 1.8, 0.3, 1.8, 1.3, 1.5, 1.3, 1, 0, 2.6, 0.7, 
                                                                                                                                                                    1, 2.1, 1.8, 1.8, 3.3, 2.6, 3, 1.2, NA, NA, 0.7, NA, NA, 1, NA, 
                                                                                                                                                                    NA, 0.7, 0.9, 0.5, 1, 0.6, NA, 3.3, 0.2, NA, 1, 0.7, 1.3, 1.7, 
                                                                                                                                                                    2.3, NA, 1.7, 1.6, 1.6, 2.5, 1.2, 2, 2.5, 2.8, 3.8, 0.7, 0, 0.2, 
                                                                                                                                                                    1.2, 2.2, NA, 1.2, 1.8, 2, 2.5, 1.8, 2.2, 2, 1.7, NA, 1.7, 2.5, 
                                                                                                                                                                    2, 1.8, 2.5, 1.8, 1.8, 3.2, 3.3, 0.6, 0.5, 1, 2.9, 1.8, 2.6, 
                                                                                                                                                                    1, 0.5, 1.2, 0.8, 0.7, 1, 1.8, 1.5, 1.8, 1.7, 0.7, 1, 1.2, 1, 
                                                                                                                                                                    0.9, 1.8, NA, NA, 2.6, 2.3, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
                                                                                                                                                                    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
                                                                                                                                                                    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
                                                                                                                                                                    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), class = c("tbl_df", 
                                                                                                                                                                                                                                        "tbl", "data.frame"), row.names = c(NA, -216L))

当我的ypu正确时,可以这样实现。按 id 分组,添加滞后值,检查差异是否大于 .5:

library(dplyr)

ds <- structure(list(id_1 = c(
  1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
  5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11,
  11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16,
  17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22,
  22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27,
  27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32,
  33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38,
  38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43,
  43, 44, 44, 44, 45, 45, 45, 46, 46, 46, 47, 47, 47, 48, 48, 48,
  49, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53, 53, 54,
  54, 54, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
  NA, NA, NA, NA, NA, NA, NA, NA
), time = structure(c(
  1L, 2L, 3L,
  1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
  2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L,
  3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L,
  1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
  2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L,
  3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L,
  1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L,
  2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L,
  3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L,
  1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, NA,
  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
  NA, NA, NA, NA, NA
), .Label = c(
  "Baseline", "Post-intervention",
  "3-month follow-up"
), class = "factor"), acq_6 = c(
  1.5, 0.8,
  0.5, 1, 0, NA, 0.5, 0.5, 0.3, 3.1, 1.5, NA, 3.1, 0.8, 1.2, 1,
  0.3, 0, 3.8, 2.7, 0.3, 4, 2, NA, 0.5, 0.8, 1, 2.2, 2.1, NA, 1.5,
  0.7, 0.7, 1.9, 0.5, 0.3, 3.7, 1.9, 2.5, 0.8, 1.3, 1, 2, 3.3,
  3.3, 2.1, 1.6, 2.2, 2.2, 1.3, 2.3, 2, 0.5, 0.5, 1.7, 1.9, 1.5,
  1.8, 1.4, NA, 2.9, 1.8, 0.3, 1.8, 1.3, 1.5, 1.3, 1, 0, 2.6, 0.7,
  1, 2.1, 1.8, 1.8, 3.3, 2.6, 3, 1.2, NA, NA, 0.7, NA, NA, 1, NA,
  NA, 0.7, 0.9, 0.5, 1, 0.6, NA, 3.3, 0.2, NA, 1, 0.7, 1.3, 1.7,
  2.3, NA, 1.7, 1.6, 1.6, 2.5, 1.2, 2, 2.5, 2.8, 3.8, 0.7, 0, 0.2,
  1.2, 2.2, NA, 1.2, 1.8, 2, 2.5, 1.8, 2.2, 2, 1.7, NA, 1.7, 2.5,
  2, 1.8, 2.5, 1.8, 1.8, 3.2, 3.3, 0.6, 0.5, 1, 2.9, 1.8, 2.6,
  1, 0.5, 1.2, 0.8, 0.7, 1, 1.8, 1.5, 1.8, 1.7, 0.7, 1, 1.2, 1,
  0.9, 1.8, NA, NA, 2.6, 2.3, NA, NA, NA, NA, NA, NA, NA, NA, NA,
  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
  NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA
)), class = c(
  "tbl_df",
  "tbl", "data.frame"
), row.names = c(NA, -216L))

ds %>% 
  group_by(id_1) %>% 
  mutate(acq_6_lag = lag(acq_6),
         get_better = ifelse(acq_6_lag - acq_6 > .5, 1, 0))
#> # A tibble: 216 x 5
#> # Groups:   id_1 [55]
#>     id_1 time              acq_6 acq_6_lag get_better
#>    <dbl> <fct>             <dbl>     <dbl>      <dbl>
#>  1     1 Baseline            1.5      NA           NA
#>  2     1 Post-intervention   0.8       1.5          1
#>  3     1 3-month follow-up   0.5       0.8          0
#>  4     2 Baseline            1        NA           NA
#>  5     2 Post-intervention   0         1            1
#>  6     2 3-month follow-up  NA         0           NA
#>  7     3 Baseline            0.5      NA           NA
#>  8     3 Post-intervention   0.5       0.5          0
#>  9     3 3-month follow-up   0.3       0.5          0
#> 10     4 Baseline            3.1      NA           NA
#> # ... with 206 more rows

reprex package (v0.3.0)

于 2020-03-16 创建