【问题标题】:how to select categories that are in one dataset, but not in another in R [duplicate]如何选择一个数据集中的类别,而不是 R [重复]
【发布时间】:2021-12-31 10:17:57
【问题描述】:

有 2 个数据集

s=structure(list(var1 = c("a", "f", "k", "tt", "ee"), var2 = c("b", 
"g", "l", "qq", "rr"), var3 = c("c", "h", "m", "ff", "cc"), var4 = c("d", 
"i", "n", "gg", "vv"), var5 = c("e", "j", "o", "aa", "xx"), metric_var = c(100L, 
200L, 300L, 567L, 789L)), class = "data.frame", row.names = c(NA, 
-5L))

medagger=structure(list(var1 = c("a", "z", "w", "f", "k"), var2 = c("b", 
"u", "e", "g", "l"), var3 = c("c", "p", "r", "h", "m"), var4 = c("d", 
"q", "q", "i", "n"), var5 = c("e", "n", "w", "j", "o"), metric_var = c(100L, 
200L, 400L, 500L, 700L)), class = "data.frame", row.names = c(NA, 
-5L))

var1-var5 是分类变量,它们的值是分类。 如果我们做一个内部连接 ​​s 和一个 medagger 我们得到这个结果

merge(s,medagger,by=c("var1","var2","var3","var4","var5"))
  var1 var2 var3 var4 var5 metric_var.x metric_var.y
1    a    b    c    d    e          100          100
2    f    g    h    i    j          200          500
3    k    l    m    n    o          300          700

只返回 3 行,因为在这些数据集中有相同的类别。 但是,我需要 s 数据集中但 medagger 数据集中没有的类别 被放在单独的数据框中。 在这种情况下,我需要出现 new 数据框,它将仅包含来自 s 的这些行中的 2 行。

var1    var2    var3    var4    var5    metric_var
tt  qq  ff  gg  aa  567
ee  rr  cc  vv  xx  789

如何使s 中但不在medagger 中的类别出现在new 数据框中? 谢谢。

【问题讨论】:

标签: r dplyr


【解决方案1】:

您需要来自dplyr 库的anti_join 才能获得预期的结果。根据文档:

anti_join() 返回 x 中没有 y 匹配的所有行。

documentation

library(dplyr)

df <- s %>%
  anti_join(medagger, by = c("var1","var2","var3","var4","var5"))

输出将是这样的:

  var1 var2 var3 var4 var5 metric_var
1   tt   qq   ff   gg   aa        567
2   ee   rr   cc   vv   xx        789

【讨论】:

    【解决方案2】:

    我认为反连接是最好的方法。

    基础 R

    虽然 dplyr::anti_join 是一个方便的一次性函数,但如果您更喜欢基本 R,那么 mergesetdiff 的两步操作:

    merged <- merge(s,medagger,by=c("var1","var2","var3","var4","var5"), suffixes = c("",".y"))
    setdiff(s, merged[,colnames(s)])
    #   var1 var2 var3 var4 var5 metric_var
    # 1   tt   qq   ff   gg   aa        567
    # 2   ee   rr   cc   vv   xx        789
    

    数据表

    data.tableDT1[!DT2] 是其规范的反连接机制,它只需要在 DT1 上设置键。

    library(data.table)
    sDT <- as.data.table(s)
    medaggerDT <- as.data.table(medagger)
    setkeyv(sDT, c("var1","var2","var3","var4","var5")) # or setkey(S, var1, ...)
    sDT[!medaggerDT]
    #    var1 var2 var3 var4 var5 metric_var
    # 1:   ee   rr   cc   vv   xx        789
    # 2:   tt   qq   ff   gg   aa        567
    

    【讨论】:

      【解决方案3】:
      library(dplyr)
      s %>% inner_join(medagger, by=c("var1","var2","var3","var4","var5")) -> result1
      
        var1 var2 var3 var4 var5 metric_var.x metric_var.y
      1    a    b    c    d    e          100          100
      2    f    g    h    i    j          200          500
      3    k    l    m    n    o          300          700
      

      和第二个数据框:

      s %>% anti_join(medagger, by=c("var1","var2","var3","var4","var5")) -> result2
        var1 var2 var3 var4 var5 metric_var
      1   tt   qq   ff   gg   aa        567
      2   ee   rr   cc   vv   xx        789
      

      在基础 R 中,假设 medagger 和 s 没有 NA,这可以工作:

      merge(s,medagger,by=c("var1","var2","var3","var4","var5"), all.x=T) -> result
      result2  <- result[!complete.cases(result),]
      

      【讨论】:

        【解决方案4】:

        你可以rbind每一行看看是不是duplicated

        s[apply(s, 1, \(x) tail(!duplicated(rbind(medagger[1:5], x[1:5])), 1)), ]
        #   var1 var2 var3 var4 var5 metric_var
        # 4   tt   qq   ff   gg   aa        567
        # 5   ee   rr   cc   vv   xx        789
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-03-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-05
          • 2015-12-04
          • 2020-03-31
          • 1970-01-01
          相关资源
          最近更新 更多