数据转换:我正在R中寻找一种有效的方法来重新编码/扩展多对一以进行生存分析



我正在研究移植术后(CABG(的通畅性

在冠状动脉搭桥术中,一名患者通常会接受一次以上的移植物(搭桥(,我们正在观察失败的时间。这在原始数据中由一个变量表示,该变量指示失败移植物的数量和诊断时间。

我的原始数据目前是每个患者一行,我认为我需要为每个移植物一行,以便继续进行KM和Cox分析。我正在考虑各种if/then循环,但不知道是否有更有效的方法在这里重新编码。

示例数据:

Patient VeinGrafts   VeinsOccluded   Months
   1        2               0           36
   2        4               1           34
   3        3               2           38
   4        4               0           33

为了观察这一点;每静脉";我需要重新编码,使每个#VeinGraft都有自己的行,并且VeinsOccluded变成1/0

我需要每行复制(静脉移植物(次数,这样患者2将有4行,但其中一行有静脉闭塞指示器,另3行没有

这就是我下一步分析所需要的上述数据。

Patient VeinGrafts   VeinsOccluded   Months
   1        2               0           36
   1        2               0           36
   2        4               1           34
   2        4               0           34
   2        4               0           34
   2        4               0           34
   3        3               1           38
   3        3               1           38
   3        3               0           38
   4        4               0           33
   4        4               0           33
   4        4               0           33
   4        4               0           33

这个社区在这一点上提供了难以置信的帮助,但我还没有找到类似的问题的答案——如果我忽略了,我很抱歉,但非常感谢你的任何想法!

我们可以uncount来展开数据,然后按"Patient"分组,mutate通过在"VeinsOccluded"的first值上创建一个具有row_number()的逻辑表达式来对"VeninsOccluded"进行分组,并使用+ 强制为二进制

library(dplyr)
library(tidyr)
df1 %>%
    uncount(VeinGrafts, .remove = FALSE) %>%
    group_by(Patient) %>% 
    mutate(VeinsOccluded = +(row_number() <= first(VeinsOccluded))) %>%
    ungroup %>%
    select(names(df1))

-输出

# A tibble: 13 x 4
#   Patient VeinGrafts VeinsOccluded Months
#     <int>      <int>         <int>  <int>
# 1       1          2             0     36
# 2       1          2             0     36
# 3       2          4             1     34
# 4       2          4             0     34
# 5       2          4             0     34
# 6       2          4             0     34
# 7       3          3             1     38
# 8       3          3             1     38
# 9       3          3             0     38
#10       4          4             0     33
#11       4          4             0     33
#12       4          4             0     33
#13       4          4             0     33

或者这可以用data.table(可能以更有效的方式(来完成

library(data.table)
setDT(df1)[rep(seq_len(.N), VeinGrafts)][,
   VeinsOccluded := +(seq_len(.N) <= first(VeinsOccluded)), Patient][]

-输出

#      Patient VeinGrafts VeinsOccluded Months
# 1:       1          2             0     36
# 2:       1          2             0     36
# 3:       2          4             1     34
# 4:       2          4             0     34
# 5:       2          4             0     34
# 6:       2          4             0     34
# 7:       3          3             1     38
# 8:       3          3             1     38
# 9:       3          3             0     38
#10:       4          4             0     33
#11:       4          4             0     33
#12:       4          4             0     33
#13:       4          4             0     33

数据

df1 <- structure(list(Patient = 1:4, VeinGrafts = c(2L, 4L, 3L, 4L), 
    VeinsOccluded = c(0L, 1L, 2L, 0L), Months = c(36L, 34L, 38L, 
    33L)), class = "data.frame", row.names = c(NA, -4L))

最新更新