У меня есть данные о событиях на уровне населения, т.е. на каждый день есть сумма лиц с событиями и лицами, подвергнутыми цензуре. Я хотел бы расширить эти данные до более традиционного формата для анализа выживаемости, т.е. каждому индивидууму присваивается ряд. Таким образом, для каждого дня необходимо добавить несколько строк для количества событий (с событиями = 1 и цензором = 0) и для количества цензоров (с событиями = 0 и цензором = 1). Ниже приведен пример фрейма входных данных (dataIn
) и желаемого вывода.
days <- c(1,2,3)
event <- c(2,2,0)
censor <- c(0,2,2)
dataIn <- data.frame(days, event, censor)
days event censor
1 2 0
2 2 2
3 0 2
days event censor
1 1 0
1 1 0
2 1 0
2 1 0
2 0 1
2 0 1
3 0 1
3 0 1
Вот довольно простой, но эффективный способ сделать это с помощью rep
:
with(dataIn, data.frame(day = c(rep(days, event), rep(days, censor)),
event = rep(c(1, 0), c(sum(event), sum(censor))),
censor = rep(c(0, 1), c(sum(event), sum(censor)))))
#> day event censor
#> 1 1 1 0
#> 2 1 1 0
#> 3 2 1 0
#> 4 2 1 0
#> 5 2 0 1
#> 6 2 0 1
#> 7 3 0 1
#> 8 3 0 1
pmap
позволяет нам применять функцию к каждой строке (дню). Затем мы можем положиться на повторное использование векторов, чтобы заполнить нули и дни. Обратите внимание, что bind_rows(tibble(), tibble())
не выдает ошибку.
pmap_dfr(dataIn, ~ list(
tibble(days = ..1, event = rep(1, ..2), censor = 0),
tibble(days = ..1, event = 0, censor = rep(1, ..3))
)
)
# A tibble: 8 x 3
days event censor
<dbl> <dbl> <dbl>
1 1 1 0
2 1 1 0
3 2 1 0
4 2 1 0
5 2 0 1
6 2 0 1
7 3 0 1
8 3 0 1
Мы могли бы использовать uncount
library(dplyr)
library(tidyr)
dataIn %>%
uncount(event + censor) %>%
mutate(across(event:censor, ~ +(. > 0)))
-выход
days event censor
1 1 1 0
2 1 1 0
3 2 1 1
4 2 1 1
5 2 1 1
6 2 1 1
7 3 0 1
8 3 0 1