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

У меня есть следующий набор данных:

individual number treatment
1          1       AAAA
1          2       BBBB
1          3       CCCC
1          4       EEEE
1          5       XXXX
1          7       WWWW
2          2       EEEE
2          3       AAAA
2          5       RRRR

Пациенты могут пройти до 7 процедур, но некоторые могут пройти только до 5 процедур (как в примере ниже индивидуальный_идентификатор = 2). Мне нужно добавить новые строки для каждого индивидуума до максимального количества обработок, которые они предпринимают (например, индивидуальный_ид = 1 до 7, индивидуальный_ид = 2 до 5) с обработкой = NA. Я хотел бы что-то вроде этого:

   individual_id number treatment
    1              1       AAAA
    1              2       BBBB
    1              3       CCCC
    1              4       EEEE
    1              5       XXXX
    1              6       NA
    1              7       WWWW
    2              1       NA
    2              2       EEEE
    2              3       AAAA
    2              4       NA
    2              5       RRRR

Может кто-нибудь посоветовать самый быстрый способ сделать это?

Я не могу поделиться своими данными, но это составленный набор данных, который точно такой же, но меньшего размера и виртуальные данные:

> dput(df)
structure(list(individual_id = c(21L, 21L, 21L, 21L, 21L, 21L, 
22L, 22L, 22L, 22L, 22L, 22L, 23L, 23L, 23L, 23L, 23L, 23L, 24L, 
24L, 24L, 24L, 24L, 24L, 24L, 24L, 24L, 24L, 24L, 24L, 25L, 25L, 
25L, 25L, 25L, 25L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 
26L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 
26L, 26L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 
27L), number = c(2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 7, 7, 7, 
7, 7, 7, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4), treatment = structure(c(3L, 
3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 4L, 4L, 4L, 4L, 4L, 
4L, 1L, 1L, 1L, 1L, 1L, 1L, 3L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 
2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 4L, 
4L, 4L, 4L, 4L, 4L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
2L, 3L, 3L, 3L, 3L, 3L, 3L), .Label = c("Adalimumab", "Etanercept", 
"Infliximab", "Rituximab"), class = "factor")), row.names = c(NA, 
-72L), class = "data.frame")

Ответы [ 2 ]

0 голосов
/ 05 апреля 2019

Подумайте о создании вспомогательного фрейма данных для всех возможных пар индивидуальных номеров и номеров процедур, а затем выполните объединение влево с исходным набором данных.

Ниже by делится на отдельный , чтобы итеративно построить фрейм данных, используя expand.grid для всех парных комбинаций отдельный и число . Наконец, do.call связывает список фреймов данных группового подмножества в один конечный фрейм данных: fill_df .

fill_df <- do.call(rbind, by(df, df$individual, function(sub) 
                                expand.grid(individual = unique(sub$individual),
                                            number = 1:max(sub$number))
                          )
                  )

final_df <- merge(fill_df, df, all.x=TRUE)
final_df

#    individual number treatment
# 1           1      1      AAAA
# 2           1      2      BBBB
# 3           1      3      CCCC
# 4           1      4      EEEE
# 5           1      5      XXXX
# 6           1      6      <NA>
# 7           1      7      WWWW
# 8           2      1      EEEE
# 9           2      2      <NA>
# 10          2      3      AAAA
# 11          2      4      <NA>
# 12          2      5      RRRR
0 голосов
/ 05 апреля 2019

Мы можем использовать для этого:

library(tidyverse)

df %>% group_by(individual) %>% 
  complete(nesting(individual), number = seq(min(number), max(number), 1))


# # A tibble: 12 x 3
# # Groups:   individual [2]
#   individual number treatment
#        <int>  <dbl>     <fct>    
# 1          1      1      AAAA     
# 2          1      2      BBBB     
# 3          1      3      CCCC     
# 4          1      4      EEEE     
# 5          1      5      XXXX     
# 6          1      6        NA       
# 7          1      7      WWWW     
# 8          2      1      EEEE     
# 9          2      2        NA       
# 10         2      3      AAAA     
# 11         2      4        NA       
# 12         2      5      RRRR   

Примечание: Для этой конкретной проблемы, основываясь на комментариях ниже, number = seq(min(number), max(number), 1) ...должно быть number = seq(1, max(number), 1), поскольку 1 всегда является первым number независимо от того, существует он в записях или нет.Но я оставил все как есть в приведенных выше строках, поскольку это казалось более общим решением.

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