通过根据数据框中的数字添加行和值来扩展数据框
Expand dataframe by adding rows and values based on numbers in dataframe
我有人口级别的事件数据,即每天都有发生事件的个人和被审查的个人的总和。我想将此数据扩展为更传统的生存分析格式,即每个人得到一行。因此,对于每一天,需要为事件数(事件数 = 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
我有人口级别的事件数据,即每天都有发生事件的个人和被审查的个人的总和。我想将此数据扩展为更传统的生存分析格式,即每个人得到一行。因此,对于每一天,需要为事件数(事件数 = 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