【问题标题】:r cumulative sum function, conditionsr 累积和函数,条件
【发布时间】:2015-04-22 11:46:01
【问题描述】:

我在 R 中有一个数据框,相当大的 600 行/观察

一列是patientId 不是数字形式,例如ju89、ju87,所以它是一个因子列

一列是remission 1/0,其中 1 表示缓解 0 表示不缓解

一栏是timefromdiagnosis

现在,从诊断开始,患者从 1 到 0、0 到 0、0 到 1 或 1 到 1

我想在它所在的数据框中添加一列

  • 1 患者缓解时为 0
  • 2 当患者正好有 1 次缓解且他最后一次有 0 或有 1 次缓解和他最后一次有 1 缓解或有 1 缓解时,这是他的第一次观察
  • 3 当患者有 1 次缓解且最近 2 次或更多次有 1 次缓解时

我曾考虑在plyr 中使用 cum sum 进行此操作,但它不适合我想做的事情,或者不太清楚如何适应

数据框已经排序,因此患者 ID 彼此相邻,并且随着您阅读数据框,每个患者的诊断时间都会增加

由于机密性,我无法提供数据框,但在这里它看起来像是为了澄清事情

remission timefromdiag patientid ...(other variables)

这是我开始使用的数据:

patientId  timefromdiagnosis  remission
ju67       1.2                1
ju67       1.6                0
ju67       3                  0
ju88       1.5                1
ju88       2                  1
ju23       1.9                1
ju23       5                  0

这是我想要得到的,疾病阶段是我想要的列:

patientId  timefromdiagnosis  remission  disease stage
ju67       1.2                1          2
ju67       1.6                0          1
ju67       3                  0          1
ju88       1.5                1          2
ju88       2                  1          2
ju23       1.9                1          2
ju23       5                  0          1
ju38       1.7                1          2
ju38       1.9                1          2 
ju38       3                  1          3
ju38       4                  1          3
ju38       5                  0          1

注意患者ju38 是如何达到 3 的,因为他已经连续 3 次缓解,包括现在的时间(最近两次缓解和现在),然后他停留在 3,因为他只是有另一个缓解,然后他进入疾病阶段 1因为他的缓解率为0。

患者ju88 在 t=2 时已缓解,在最后一次 t=1.5 时已缓解,但这只是包括 t=2 在内的两次连续缓解,因此他处于疾病 2 期

患者ju23 在 t=1.9,缓解期为 1,这是对他的第一次观察,因此他满足疾病第 2 期的标准,如果他的缓解期为 0,他将处于疾病期 1

p>

【问题讨论】:

    标签: r cumsum


    【解决方案1】:

    您使用的是患者处于缓解期的连续周期数,每当患者缓解期时重置该计数器。我认为缓解变量的行程编码因此很有趣。您可以使用rle 函数计算它:

    dat$diseaseStage <- ave(dat$remission, dat$patientId, FUN=function(x) {
      ret <- unlist(lapply(rle(x)$length, function(y) c(rep(2, min(2, y)), rep(3, max(0, y-2)))))
      ret[x == 0] <- 1
      ret
    })
    dat
    #    patientId timefromdiagnosis remission diseaseStage
    # 1       ju67               1.2         1            2
    # 2       ju67               1.6         0            1
    # 3       ju67               3.0         0            1
    # 4       ju88               1.5         1            2
    # 5       ju88               2.0         1            2
    # 6       ju23               1.9         1            2
    # 7       ju23               5.0         0            1
    # 8       ju38               1.7         1            2
    # 9       ju38               1.9         1            2
    # 10      ju38               3.0         1            3
    # 11      ju38               4.0         1            3
    # 12      ju38               5.0         0            1
    

    请注意,这适用于患者多次进入和退出缓解的更复杂的情况:

    dat2 <- data.frame(patientId=rep("x", 12), remission=rep(c(1, 0, 1, 0), each=3))
    

    使用相同的函数,我们得到:

    #    patientId remission diseaseStage
    # 1          x         1            2
    # 2          x         1            2
    # 3          x         1            3
    # 4          x         0            1
    # 5          x         0            1
    # 6          x         0            1
    # 7          x         1            2
    # 8          x         1            2
    # 9          x         1            3
    # 10         x         0            1
    # 11         x         0            1
    # 12         x         0            1
    

    请注意,在这种情况下使用 cumsum 是不够的,因为它不会反映我们在第 4-6 行中摆脱缓解的事实。

    【讨论】:

    • 非常感谢您的回复,您是如何这么快找到解决方案的?您能否更详细地解释第二行和更多行,只是出于兴趣:),y是什么? x是什么?为什么我们要“重复”,我觉得最小最大值是有道理的,但不太明白
    • @RampageKyd R 是一种函数式编程语言,因此我定义了对数据片段进行操作的函数。外部函数获取缓解变量的片段,调用它们x,然后对它们进行操作。内部函数获取rle(x)$length 的各个元素,调用它们y,并对它们进行操作。
    猜你喜欢
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    • 1970-01-01
    • 2016-01-04
    • 2022-12-05
    • 1970-01-01
    相关资源
    最近更新 更多