【问题标题】:R Duplicate Join FunctionR重复连接功能
【发布时间】:2017-03-27 16:44:17
【问题描述】:

当我有重复值并想保留第一个值时,我在使用 dplyr 的连接函数时遇到了问题,因此我决定编写自己的函数。如果有一个功能已经这样做了,请告诉我!它可能写得更好,更有效。

这是带有一些示例数据的代码:

dt1 <- data.table(A = c(rep(1, 3), rep(2, 3)), B = rep(1:3, 2),
                  C = runif(n = 6, min = 0, max = 10))
dt2 <- data.table(A = c(rep(3, 3), rep(4, 3)), B = rep(1:3, 2),
                  C = runif(n = 6, min = 0, max = 10))
dt3 <- data.table(A = c(rep(3, 3), rep(4, 3)), B = rep(1:3, 2),
                  D = runif(n = 6, min = 0, max = 10))
dt4 <- data.table(A = c(rep(2, 3), rep(3, 3)), B = rep(1:3, 2),
                  D = runif(n = 6, min = 0, max = 10))

dt5 <- duplicate_join(dt1, dt2)
dt6 <- duplicate_join(dt5, dt3)
dt7 <- duplicate_join(dt6, dt4)

duplicate_join <- function(dt1, dt2) {

  melt1 <- dt1 %>%
    gather(variable, value, -c(A, B), na.rm = TRUE)
  melt2 <- dt2 %>%
    gather(variable, value, -c(A, B), na.rm = TRUE)

  join <- rbindlist(list(melt1, melt2), use.names = TRUE) %>%
    distinct(A, B, variable, .keep_all = TRUE) %>%
    spread(variable, value)
  join
}

我的问题是让用户决定收集哪些列并检查重复值。在这种情况下,将AB 变成一个通用表达式。我已经阅读了FunctionsCapturing Un-evaluated Dots,并查看了一些执行此操作的函数的源代码 (ggplot),但没有任何意义。我尝试了很多技术并得到错误object 'A' not foundinvalid argument to unary operator

函数调用是否对我来说无关紧要:

duplicate_join <- function(dt1, dt2, ...) {}

或者:

duplicate_join <- function(dt1, dt2, cols) {}

我只需要知道如何让...cols 在函数内工作!谢谢!

【问题讨论】:

    标签: r function dplyr


    【解决方案1】:

    你正在寻找来自 Dplyr 包的 Semi Join

    说明:

    semi_join(x, y):返回 x 中在 y 中有匹配值的所有行,只保留 x 中的列。半连接与内连接不同,因为内连接将为 y 的每个匹配行返回一行 x,其中半连接永远不会复制 x 的行。这是一个过滤连接。

    在此处使用您的代码是 semi_join 的示例:

    #Semi Joining by equality of "B" Columns, Keeping dt1, 
    #if you want to keep dt2, just change the parameters order
    dt4 <- semi_join(dt1, dt2, by = c("B" = "B"))
    
    Output:
    
      A B         C
    1 1 1 5.3330819
    2 2 1 0.1652472
    3 1 2 4.6283878
    4 2 2 1.5570931
    5 1 3 9.6967720
    6 2 3 1.1587919
    
    #Semi Joining: Multiple Columns
    dt5 <- semi_join(dt1, dt2, by = c("A" = "A", "B" = "B"))
    #No output, there's no rows that satisfy "A" = "A" and "B" = "B"
    

    【讨论】:

    • 非常感谢您的帮助,Cayoda!不幸的是,semi_join 不起作用,因为如您的示例所示,它不适用于多列情况。它在第一种情况下确实不起作用,因为它更改了“A”列中的值。
    猜你喜欢
    • 1970-01-01
    • 2018-09-03
    • 2020-07-24
    • 1970-01-01
    • 2016-11-27
    • 2020-10-29
    • 2017-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多