代码之家  ›  专栏  ›  技术社区  ›  string

根据组和另一个数据帧删除R数据帧中的行

  •  0
  • string  · 技术社区  · 8 年前

    dat1 <- data.frame(group= c(11,11,12,12,13,13,14,14,15,15,16,16,17,17,17,18,18,18),name= c("A","B","C","D","E","F","G","H","I","J","A","B","E","F","W","A","B","V"))
    
    dat2 <- data.frame(ID=c(1,1,2,2,3,3),name =c("A","B","E","F","X","Y"))
    

    dat2中存在组组合。

    二者都

    因此,期望的输出是

    desiredat <- data.frame(group= c(12,12,13,13,15,15),name= c("C","D","G","H","I","J"))
    

    在R中寻找实现相同目标的方法。

    2 回复  |  直到 8 年前
        1
  •  0
  •   Community Mohan Dere    6 年前

    这可以通过 反连接 . 但是,我们需要确定哪些组ID group 必须从 dat1

    library(data.table)
    # count names per ID
    setDT(dat2)[, n.id := .N, by = ID]
    # identify groups to remove by joining and ... 
    groups_to_remove <- dat2[setDT(dat1), on = "name", nomatch = 0L][
      # ... check which groups have a match with the complete set of names
      , which(n.id == .N), by = .(ID, group)]
    # anti join
    dat1[!groups_to_remove, on = "group"]
    
       group name
    1:    12    C
    2:    12    D
    3:    14    G
    4:    14    H
    5:    15    I
    6:    15    J
    7:    19    A
    8:    19    X
    

    第19组是 dat2


    更精简的方法使用 all()

    library(data.table)
    setDT(dat1)
    setDT(dat2)
    groups_to_remove <- dat1[dat2, on = "name"][, which(all(ID == ID[1])), by = group]
    dat1[!groups_to_remove, on = "group"]
    
    1: 12摄氏度
    3: 14克
    5: 15英寸
    6: 15焦耳
    8: 19倍
    

    同上 dplyr 语法:

    library(dplyr)
    dat2 %>% 
      left_join(dat1, by = "name") %>% 
      group_by(group) %>% 
      summarise(all_have_same_id = all(ID == ID[1L])) %>% 
      filter(all_have_same_id) %>% 
      anti_join(dat1, ., by = "group")
    
      group name
    1    12    C
    2    12    D
    3    14    G
    4    14    H
    5    15    I
    6    15    J
    7    19    A
    8    19    X
    Warning message:
    Column `name` joining factors with different levels, coercing to character vector
    

    数据

    示例数据集 由OP提供的组由不包含名称的组组成 数据2 或者所有的名字都在一个ID中 数据2 数据2 . 因此,我添加了这个用例(作为组19):

    dat1 <- data.frame(
      group= c(11,11,12,12,13,13,14,14,15,15,16,16,17,17,17,18,18,18,19,19),
      name= c("A","B","C","D","E","F","G","H","I","J","A","B","E","F","W","A","B","V","A","X"))
    
    dat2 <- data.frame(ID=c(1,1,2,2,3,3),name =c("A","B","E","F","X","Y"))
    
        2
  •  0
  •   Jilber Urbina    8 年前

    像这样。。。?

    dat1[dat1$name %in% setdiff(dat1$name, dat2$name), ]
    3     12    C
    4     12    D
    7     14    G
    8     14    H
    9     15    I
    10    15    J
    15    17    W
    18    18    V