【问题标题】:R: Delete ID if any of the rows within ID contain specific strings (or multiple partial strings) in longitudinal format?R:如果 ID 中的任何行包含纵向格式的特定字符串(或多个部分字符串),则删除 ID?
【发布时间】:2022-02-10 05:54:42
【问题描述】:

我想删除 ID 中包含某些字符串(A 或 D)的任何行中的 ID。 这是我的数据框:

id   time   dx
1     1     C
1     2     B
2     1     A
2     2     C
2     3     B
3     1     D

我想要以下内容:

id    time  dx
 1     1     C
 1     2     B

基于之前关于此的帖子 (Delete rows containing specific strings in R),我尝试了 d %>% filter(!grepl('A|D', dx))。但是,它只删除包含 A 或 D 的行,而不是整个 ID。如有任何帮助,我将不胜感激!

##Update:以下所有答案都适用于上述帖子。谢谢你们!请注意,对于这篇文章,我简化了我的数据框,后来,我意识到我实际上需要 R 代码来从以下数据框中删除带有某些部分字符串(例如 A 或 B0)的 ID。我能够通过修改第一个 r2evans 的答案来实现这一点:d %>% group_by(id) %>% filter(!any(str_detect(dx, "A|B0"))) %>% ungroup()。我已经在此处包含了注释,以防有人需要它。如果有任何其他建议,我将不胜感激。

数据框:

id time dx
1   1   C01
1   2   B1
2   1   A34
2   2   C01
2   3   B1
3   1   B01X

我想要的结果:

id time dx
1   1   C01
1   2   B1

【问题讨论】:

    标签: r string dplyr delete-row longitudinal


    【解决方案1】:

    grep 是基于您的问题和示例数据的错误工具,我认为%in% 是更好的方法。将它与自然的dplyr:group_byany(.) 条件结合起来,我们就得到了结果

    dplyr

    dat %>%
      group_by(id) %>%
      filter(!any(dx %in% c("A", "D"))) %>%
      ungroup()
    # # A tibble: 2 x 3
    #      id  time dx   
    #   <int> <int> <chr>
    # 1     1     1 C    
    # 2     1     2 B    
    

    基础 R

    dat[ave(dat$dx, dat$id, FUN = function(z) !any(z %in% c("A", "D"))) == "TRUE",]
    #   id time dx
    # 1  1    1  C
    # 2  1    2  B
    

    (ave 要求其输出与其输入相同,在本例中为 character。这就是为什么我要与 string "TRUE" 进行比较而不是将其用作文字 TRUE。)


    数据

    dat <- structure(list(id = c(1L, 1L, 2L, 2L, 2L, 3L), time = c(1L, 2L, 1L, 2L, 3L, 1L), dx = c("C", "B", "A", "C", "B", "D")), class = "data.frame", row.names = c(NA, -6L))
    

    【讨论】:

    • 谢谢你,r2evans!两者都有效。我赞成你的回答。
    【解决方案2】:

    我们可以在base R 中使用subset

    subset(df1, !id %in% id[dx %in% c("A", "D")])
      id time dx
    1  1    1  C
    2  1    2  B
    

    filter 的类似选项来自dplyr

    library(dplyr)
    filter(df1, !id %in% id[dx %in% c("A", "D")])
      id time dx
    1  1    1  C
    2  1    2  B
    

    数据

    df1 <- structure(list(id = c(1L, 1L, 2L, 2L, 2L, 3L), time = c(1L, 2L, 
    1L, 2L, 3L, 1L), dx = c("C", "B", "A", "C", "B", "D")), 
    class = "data.frame", row.names = c(NA, 
    -6L))
    

    【讨论】:

    • 谢谢你,阿克伦!两者都有效。我赞成你的回答。
    【解决方案3】:

    另一个使用 subset + ave 的基本 R 选项

    subset(
      df,
      !ave(dx %in% c("A", "D"), id, FUN = any)
    )
    

    给予

      id time dx
    1  1    1  C
    2  1    2  B
    

    【讨论】:

    • 谢谢您,ThomasisCoding!有效。我赞成你的回答。
    猜你喜欢
    • 1970-01-01
    • 2017-11-16
    • 1970-01-01
    • 2019-04-25
    • 2014-04-10
    相关资源
    最近更新 更多