rbind dataframes с survival :: Surv objects - PullRequest
1 голос
/ 11 июля 2020

Как мне объединить два фрейма данных, которые включают объекты survival::Surv, чтобы поля в результирующем фрейме данных имели тот же класс, что и исходные фреймы данных?

Я обнаружил, что использование 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. Обратите внимание, что в команде 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 - это число c, а атрибут 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 не является Surv объектом

>class(df3$conc)
[1] "matrix" "array" 

Содержимое df3 выглядит немного странно, но имеет смысл, учитывая то, как выживаемость пакет хранит свои данные.

> 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

1 Ответ

1 голос
/ 12 июля 2020

Мы можем использовать 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), а затем назначить объединенный 'con c'

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
...