【问题标题】:In R, collapse over multiple logical rows of the same ID into 1 row在 R 中,将相同 ID 的多个逻辑行折叠成 1 行
【发布时间】:2021-05-25 22:14:36
【问题描述】:

问题:为了对R中的处方药使用情况做一些调查分析,我需要将同一个人(ID)的多行合二为一,如果有说的话,注明TRUE rows 中有TRUE。

这是数据:

df <- data.frame(ID = c("a","a","a","a","a","a"), 
                cardiovasc = c(T,T,T,T,T,T), 
                beta_blockers = c(F,F,F,F,F,F),
                antibiotics = c(T,F,F,F,F,F),
                stringsAsFactors=FALSE)

这是我想要的样子:

goal <- data.frame(ID = c("a"),
                    cardiovasc = c(T), 
                    beta_blockers = c(F),
                    antibiotics = c(T),
                    stringsAsFactors=FALSE)

如您所知,尽管 df$antibiotics 在数据集中只有 1 个 TRUE,但当 ID 折叠成一行时,我希望它算作 TRUE。

我的尝试:

主要是,我一直在努力解决this post,虽然我觉得我很接近,但我还是得到了一个错误。这是我的尝试:

df <- df[, lapply(.SD, paste0, collapse=""), by=ID]

产生unused argument (by = ID)。我从同一篇文章中尝试了另一种方法,但这更加混乱,需要我将数据设为data.table。我需要保存为data.frame。

有什么想法吗?

【问题讨论】:

    标签: r dataframe data.table


    【解决方案1】:

    我们可以使用any 代替paste,因为any 将检查列中的任何TRUE 元素,按“ID”分组

    library(data.table)
    setDT(df)[, lapply(.SD, any), ID]
    

    -输出

    #   ID cardiovasc beta_blockers antibiotics
    #1:  a       TRUE         FALSE        TRUE
    

    【讨论】:

      【解决方案2】:

      或者你可以使用这个tidyverse 解决方案:

      library(dplyr)
      
      df %>%
        group_by(ID) %>%
        summarise(across(cardiovasc:antibiotics, ~ any(.x)))
      
      # A tibble: 1 x 4
        ID    cardiovasc beta_blockers antibiotics
        <chr> <lgl>      <lgl>         <lgl>      
      1 a     TRUE       FALSE         TRUE
      

      更新 感谢亲爱的@Ray 提出了一个非常可能的场景: 如果列值是 1 和 0 而不是 TRUE 和 FALSE 并且还考虑到其中存在 NA 值,我们可以使用以下解决方案:

      df %>%
        group_by(ID) %>%
        summarise(across(cardiovasc:antibiotics, ~ any(.x[!is.na(.x)] == 1)))
      
      # A tibble: 1 x 4
        ID    cardiovasc beta_blockers antibiotics
        <chr> <lgl>      <lgl>         <lgl>      
      1 a     TRUE       FALSE         TRUE  
      

      数据

      df <- data.frame(ID = c("a","a","a","a","a","a"), 
                       cardiovasc = c(1,1,1,1,1,1), 
                       beta_blockers = c(0,0,0,0,0,0),
                       antibiotics = c(1,0,0,0,0,0),
                       stringsAsFactors=FALSE)
      

      【讨论】:

      • 如果在原始数据框中,cardiovasc、beta_blockers 和 antibiotics 变量只是 1/0 而不是逻辑 T/F,我将如何让您的解决方案发挥作用?我遇到了一些我认为与这些指标的逻辑类型有关的错误,我想尝试在这些变量的 1/0 版本上使用您的解决方案。我尝试用“paste”和“paste0”替换“any”,但是虽然没有发生错误,但结果数据帧没有改变。
      • 如果你想使用检查 TRUE 的any()。 any() 还将 0/1 向量强制转换为逻辑向量。因此,它应该开箱即用。但是,您必须注意 NA,因为如果您缺少值,任何将返回 NA。如果您不信任 any() 强制,请将您的 0/1“重新编码”为 TRUE/FALSE(这样您还必须处理 NA)并使用给定的解决方案。
      • 亲爱的@logjammin,我已经针对这种情况更新了我的解决方案。请立即检查。
      • 非常感谢亲爱的@Ray 让我注意到这种可能的情况。我非常感谢您的贡献。
      • 非常感谢大家的帮助——很高兴有一个 tidyverse 解决方案来解决这个问题,而且是一个灵活的解决方案。
      猜你喜欢
      • 1970-01-01
      • 2022-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-14
      • 2015-12-10
      • 2016-12-10
      • 2021-08-14
      相关资源
      最近更新 更多