rbind 数据帧与 survival::Surv 个对象
rbind dataframes with survival::Surv objects
如何合并包含 survival::Surv
对象的两个数据帧,以便生成的数据帧中的字段与源数据帧具有相同的 class?
我发现使用 rbind
会导致 Surv
对象被转换为矩阵。比如我创建了df1
如下:
library(survival)
df1 <- data.frame(obs = c('A','B','C','D','E')
, lo = c(10,20,30,40,50)
, hi = c(30,30,30,40,50))
df1$conc <-survival::Surv(df1$lo, df1$hi, type = "interval2")
接下来,我检查 df1 的内容和结构以及 df1$conc
class。请注意,在 str
命令中, conc
是 Surv
> df1
obs lo hi conc
1 A 10 30 [10, 30]
2 B 20 30 [20, 30]
3 C 30 30 30
4 D 40 40 40
5 E 50 50 50
> str(df1)
'data.frame': 5 obs. of 4 variables:
$ obs : chr "A" "B" "C" "D" ...
$ lo : num 10 20 30 40 50
$ hi : num 30 30 30 40 50
$ conc: 'Surv' num [1:5, 1:3] [10, 30] [20, 30] 30 40 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : NULL
.. ..$ : chr [1:3] "time1" "time2" "status"
..- attr(*, "type")= chr "interval"
> class(df1$conc)
[1] "Surv"
接下来,创建 df2
作为 df1
的副本,rbind df1
和 df2
一起作为 df3
。
df2 <- df1
df3 <- rbind(df1,df2)
df3
的结构看起来与上面的 df1
几乎相同,但是字段 conc
是数字并且缺少 type
属性。
>str(df3)
'data.frame': 10 obs. of 4 variables:
$ obs : chr "A" "B" "C" "D" ...
$ lo : num 10 20 30 40 50 10 20 30 40 50
$ hi : num 30 30 30 40 50 30 30 30 40 50
$ conc: num [1:10, 1:3] 10 20 30 40 50 10 20 30 40 50 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : NULL
.. ..$ : chr [1:3] "time1" "time2" "status"
另请注意 df3$conc
的 class 不是 Surv
对象
>class(df3$conc)
[1] "matrix" "array"
df3
的内容看起来有点奇怪,但考虑到 survival 包存储其数据的方式是有道理的。
> df3
obs lo hi conc.time1 conc.time2 conc.status
1 A 10 30 10 30 3
2 B 20 30 20 30 3
3 C 30 30 30 1 1
4 D 40 40 40 1 1
5 E 50 50 50 1 1
6 A 10 30 10 30 3
7 B 20 30 20 30 3
8 C 30 30 30 1 1
9 D 40 40 40 1 1
10 E 50 50 50 1 1
我们可以使用bind_rows
library(dplyr)
df3 <- bind_rows(df1, df2)
df3
# obs lo hi conc
#1 A 10 30 [10, 30]
#2 B 20 30 [20, 30]
#3 C 30 30 30
#4 D 40 40 40
#5 E 50 50 50
#6 A 10 30 [10, 30]
#7 B 20 30 [20, 30]
#8 C 30 30 30
#9 D 40 40 40
#10 E 50 50 50
如果我们需要使用 rbind
,对普通列进行子集化(conc
是一个 matrix
),然后分配串联的 'conc'
nm1 <- setdiff(names(df1), 'conc')
df3 <- rbind(df1[nm1], df2[nm1])
df3$conc <- c(df1$conc, df2$conc)
df3
# obs lo hi conc
#1 A 10 30 [10, 30]
#2 B 20 30 [20, 30]
#3 C 30 30 30
#4 D 40 40 40
#5 E 50 50 50
#6 A 10 30 [10, 30]
#7 B 20 30 [20, 30]
#8 C 30 30 30
#9 D 40 40 40
#10 E 50 50 50
如何合并包含 survival::Surv
对象的两个数据帧,以便生成的数据帧中的字段与源数据帧具有相同的 class?
我发现使用 rbind
会导致 Surv
对象被转换为矩阵。比如我创建了df1
如下:
library(survival)
df1 <- data.frame(obs = c('A','B','C','D','E')
, lo = c(10,20,30,40,50)
, hi = c(30,30,30,40,50))
df1$conc <-survival::Surv(df1$lo, df1$hi, type = "interval2")
接下来,我检查 df1 的内容和结构以及 df1$conc
class。请注意,在 str
命令中, conc
是 Surv
> df1
obs lo hi conc
1 A 10 30 [10, 30]
2 B 20 30 [20, 30]
3 C 30 30 30
4 D 40 40 40
5 E 50 50 50
> str(df1)
'data.frame': 5 obs. of 4 variables:
$ obs : chr "A" "B" "C" "D" ...
$ lo : num 10 20 30 40 50
$ hi : num 30 30 30 40 50
$ conc: 'Surv' num [1:5, 1:3] [10, 30] [20, 30] 30 40 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : NULL
.. ..$ : chr [1:3] "time1" "time2" "status"
..- attr(*, "type")= chr "interval"
> class(df1$conc)
[1] "Surv"
接下来,创建 df2
作为 df1
的副本,rbind df1
和 df2
一起作为 df3
。
df2 <- df1
df3 <- rbind(df1,df2)
df3
的结构看起来与上面的 df1
几乎相同,但是字段 conc
是数字并且缺少 type
属性。
>str(df3)
'data.frame': 10 obs. of 4 variables:
$ obs : chr "A" "B" "C" "D" ...
$ lo : num 10 20 30 40 50 10 20 30 40 50
$ hi : num 30 30 30 40 50 30 30 30 40 50
$ conc: num [1:10, 1:3] 10 20 30 40 50 10 20 30 40 50 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : NULL
.. ..$ : chr [1:3] "time1" "time2" "status"
另请注意 df3$conc
的 class 不是 Surv
对象
>class(df3$conc)
[1] "matrix" "array"
df3
的内容看起来有点奇怪,但考虑到 survival 包存储其数据的方式是有道理的。
> df3
obs lo hi conc.time1 conc.time2 conc.status
1 A 10 30 10 30 3
2 B 20 30 20 30 3
3 C 30 30 30 1 1
4 D 40 40 40 1 1
5 E 50 50 50 1 1
6 A 10 30 10 30 3
7 B 20 30 20 30 3
8 C 30 30 30 1 1
9 D 40 40 40 1 1
10 E 50 50 50 1 1
我们可以使用bind_rows
library(dplyr)
df3 <- bind_rows(df1, df2)
df3
# obs lo hi conc
#1 A 10 30 [10, 30]
#2 B 20 30 [20, 30]
#3 C 30 30 30
#4 D 40 40 40
#5 E 50 50 50
#6 A 10 30 [10, 30]
#7 B 20 30 [20, 30]
#8 C 30 30 30
#9 D 40 40 40
#10 E 50 50 50
如果我们需要使用 rbind
,对普通列进行子集化(conc
是一个 matrix
),然后分配串联的 'conc'
nm1 <- setdiff(names(df1), 'conc')
df3 <- rbind(df1[nm1], df2[nm1])
df3$conc <- c(df1$conc, df2$conc)
df3
# obs lo hi conc
#1 A 10 30 [10, 30]
#2 B 20 30 [20, 30]
#3 C 30 30 30
#4 D 40 40 40
#5 E 50 50 50
#6 A 10 30 [10, 30]
#7 B 20 30 [20, 30]
#8 C 30 30 30
#9 D 40 40 40
#10 E 50 50 50