【问题标题】:R code to detect a change in a variable over time for multiple patients用于检测多个患者随时间变化的变量的 R 代码
【发布时间】:2020-03-09 10:15:59
【问题描述】:

我有一个数据集,每个患者有多行,其中每一行代表 4 个月内的 1 周时间段。有一个变量grade 可以取123 的值,我想检测单个患者的等级何时增加(1 到 2、1 到 3 或 2 到 3 ) 在任何时候(结果将是一个是/否变量)。我可以编写一个函数来做到这一点,但我敢打赌,我可以做一些聪明的函数式编程来利用现有的 R 函数。下面是一个示例数据集。谢谢!

df=data.frame(patient=c(1,1,1,2,2,3,3,3,3),period=c(1,2,3,1,3,1,3,4,5),grade=c(1,1,1,2,3,1,1,2,3))

我想要的是结果数据框:

data.frame(patient=c(1,2,3),grade.increase=c(0,1,1))

【问题讨论】:

    标签: r data-manipulation data-cleaning


    【解决方案1】:
    library(dplyr)
    
    df %>%
      arrange(patient, period) %>%
      mutate(grade.increase = case_when(grade > lag(grade) ~ TRUE,TRUE ~ FALSE)) %>%
      group_by(patient) %>%
      summarise(grade.increase = max(grade.increase))
    

    将检查前一个值的lagcase_when 结合起来,我们可以识别每个grade.increase。

    总结每个患者的最大等级。增加得到所需的结果,因为布尔计算将 FALSE 视为 0,将 TRUE 视为 1。

    【讨论】:

    • 谢谢!我知道会有一个优雅的解决方案
    【解决方案2】:

    如果您想在基础 R 中执行此操作,这里有一个使用拆分-应用-组合方法的解决方案。

    • 您使用split 为每位患者创建一个包含单独数据框的列表;
    • 您使用lapply 对每个列表元素迭代一个汇总函数,其中汇总函数使用diff 查看gradeifany 的变化进行汇总;然后
    • 您将整个内容包装在 do.call(rbind, ...) 中,以将结果列表折叠成一个数据框。

    看起来是这样的:

    do.call(rbind, lapply(split(df, df[,"patient"]), function(i) {
    
        data.frame(patient = i[,"patient"][1],
                   grade.increase = if (any(diff(i[,"grade"]) > 0)) 1 else 0 )
    
    }))
    

    结果:

      patient grade.increase
    1       1              0
    2       2              1
    3       3              1
    

    【讨论】:

      猜你喜欢
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-24
      • 2021-02-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多