повторение числа n раз, затем другое число для оставшихся строк в R

r #replication

#r #репликация

Вопрос:

У меня есть набор данных, в котором каждая строка представляет собой ежемесячное наблюдение за пациентами, отслеживающее, дали ли они положительный результат на заболевание (статус).

Я знаю, в каком месяце (т.Е. Номер строки для каждого идентификатора — TimeToDx) они были диагностированы, и что я хотел бы сделать, так это иметь двоичный индикатор, который переключается с 0 на 1, начиная с месяца наблюдения, указанного в TimeToDx .

По сути, мне нужно реплицировать 0 к TimeToDx — 1, затем для остальных строк реплицировать 1 для каждого идентификатора.

Вот некоторые примерные данные — без заполненного индикатора состояния:

  ID TimeToDx    Status
10425   2   
10425   2   
10425   2   
10425   2   
10667   3   
10667   3   
10667   3   
10667   3   
10667   3   
10686   2   
10686   2   
10686   2   
10686   2   
10686   2   
17096   5   
17096   5   
17096   5   
17096   5   
17096   5   
 

Вот что я хотел бы видеть:

 ID  TimeToDx    Status
10425   2       0
10425   2       1
10425   2       1
10425   2       1
10667   3       0
10667   3       0
10667   3       1
10667   3       1
10667   3       1
10686   2       0
10686   2       1
10686   2       1
10686   2       1
10686   2       1
17096   5       0
17096   5       0
17096   5       0
17096   5       0
17096   5       1
 

Любая помощь будет высоко оценена.

Ответ №1:

Вот подход с dplyr . Группируя внутри каждого идентификатора, мы сравниваем строку в этой группе с TimeToDx . TRUE x 1 = 1, FALSE x 1 = 0. Можно использовать поочередно mutate(Status = if_else(row_number() >= TimeToDx, 1, 0)) .

 library(dplyr)
df %>%
  group_by(ID) %>%
  mutate(Status = 1 * (row_number() >= TimeToDx)) %>%
  ungroup()
 

Комментарии:

1. О, я понимаю. Большое спасибо, Джон, сработало для меня.

Ответ №2:

 df <- structure(list(ID = c(10425L, 10425L, 10425L, 10425L, 10667L, 
                            10667L, 10667L, 10667L, 10667L, 10686L, 10686L, 10686L, 10686L, 
                            10686L, 17096L, 17096L, 17096L, 17096L, 17096L), 
                     TimeToDx = c(2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 2L, 2L,
                                  2L, 2L, 2L, 5L, 5L, 5L, 5L, 5L)),
                class = "data.frame", row.names = c(NA, -19L))

library(tidyverse)
df %>%
  group_by(ID) %>% 
  mutate(Status =  ((row_number() %/% TimeToDx) != 0)) %>% 
  ungroup()
#> # A tibble: 19 x 3
#>       ID TimeToDx id_row
#>    <int>    <int>  <int>
#>  1 10425        2      0
#>  2 10425        2      1
#>  3 10425        2      1
#>  4 10425        2      1
#>  5 10667        3      0
#>  6 10667        3      0
#>  7 10667        3      1
#>  8 10667        3      1
#>  9 10667        3      1
#> 10 10686        2      0
#> 11 10686        2      1
#> 12 10686        2      1
#> 13 10686        2      1
#> 14 10686        2      1
#> 15 17096        5      0
#> 16 17096        5      0
#> 17 17096        5      0
#> 18 17096        5      0
#> 19 17096        5      1
 

Создано 2021-10-21 пакетом reprex (v2.0.1)

data.table

используя решение @Jon Spring

 library(data.table)
setDT(df)[, Status :=  (rowid(ID) >= TimeToDx)][]
#>        ID TimeToDx Status
#>  1: 10425        2      0
#>  2: 10425        2      1
#>  3: 10425        2      1
#>  4: 10425        2      1
#>  5: 10667        3      0
#>  6: 10667        3      0
#>  7: 10667        3      1
#>  8: 10667        3      1
#>  9: 10667        3      1
#> 10: 10686        2      0
#> 11: 10686        2      1
#> 12: 10686        2      1
#> 13: 10686        2      1
#> 14: 10686        2      1
#> 15: 17096        5      0
#> 16: 17096        5      0
#> 17: 17096        5      0
#> 18: 17096        5      0
#> 19: 17096        5      1
 

Создано 2021-10-21 пакетом reprex (v2.0.1)