【问题标题】:Parameter to check if all values have joined when joining two dataframes连接两个数据帧时检查所有值是否已连接的参数
【发布时间】:2021-06-27 08:45:43
【问题描述】:

我经常有两个希望加入的数据框,我希望所有值都加入其中。如果不是所有值都出现在两个数据框中,我希望它返回错误。

这是一个 MWE:

library(dplyr, warn.conflicts = FALSE)

df1  <- data.frame(
    id  = c(1:5),
    value1 = rep(1, 5)
)

print(df1)
#>   id value1
#> 1  1      1
#> 2  2      1
#> 3  3      1
#> 4  4      1
#> 5  5      1

df2  <- data.frame(
    id  = c(1:4),
    value2 = rep(2, 4)
)

print(df2)
#>   id value2
#> 1  1      2
#> 2  2      2
#> 3  3      2
#> 4  4      2

df3  <- inner_join(
    df1, 
    df2,
    by = "id")

print(df3)
#>   id value1 value2
#> 1  1      1      2
#> 2  2      1      2
#> 3  3      1      2
#> 4  4      1      2

# Check if all values have joined
stopifnot(
    nrow(df3) == max(nrow(df1), nrow(df2))
)
#> Error: nrow(df3) == max(nrow(df1), nrow(df2)) is not TRUE

reprex package (v1.0.0) 于 2021 年 3 月 31 日创建

这可行,但我不喜欢stopifnot()。感觉很麻烦,特别是如果我想覆盖df2,那么我需要创建一个临时值df2_previous_row_num = nrow(df2),然后再做stopifnot(nrow(df2) == df2_previous_row_num)

此外,nrow() 测试仅在 id 中的所有值都是唯一的情况下才有效。还有其他方法,例如stopifnot(c(df1$id %in% df3$id, df2$id %in% df3$id)) 但这些又是丑陋的。

我真正要寻找的是一个参数,如果某些值没有加入,它会使加入失败。比如inner_join(df1, df2, fail_if_not_all_present = TRUE)

我不喜欢 tidyverse - 如果有基本的 R 或 data.table 方式来做这件事,那么我会考虑这些。

有人知道吗?

【问题讨论】:

  • 我怀疑你很难找到一个只是的函数。例如,如果要保留一个或两个帧中的所有键,则需要左、右或全连接,而不是内连接。如果您希望所有键都存在,那么“连接​​演算”(引用 SQL 连接以及 R 的merge)中没有任何内容要求在输出中存在键。既然您认为@RonakShah 的答案不适合您,并且stopifnot 感觉不对,那么您唯一剩下的选择就是full_join 带有canary 列,然后查找NAs。这不是通用的。

标签: r dataframe dplyr data.table tidyverse


【解决方案1】:

您可以尝试编写自定义内连接函数。

custom_inner_join <- function(data1,data2,by, fail_if_not_all_present = FALSE) {
  if(fail_if_not_all_present) {
    vals1 <- do.call(paste, data1[cols])
    vals2 <- do.call(paste, data2[cols])
    if(all(vals1 %in% vals2) && all(vals2 %in% vals1)) {
      merge(data1, data2, by)
    } else stop('Not all key values are present')
  } else {
    merge(data1, data2, by)
  }
}

custom_inner_join(df1, df2, 'id')

#  id value1 value2
#1  1      1      2
#2  2      1      2
#3  3      1      2
#4  4      1      2

custom_inner_join(df1, df2, 'id', fail_if_not_all_present = TRUE)

custom_inner_join 中的错误(df1,df2,“id”,fail_if_not_all_present = TRUE): 并非所有键值都存在

【讨论】:

  • 谢谢 - 这没关系,但它似乎比使用 stopifnot() 来测试他们都加入了更多的代码。我希望有人可能知道当前包装中的现有功能。不过,我很感谢您的回复。
猜你喜欢
  • 1970-01-01
  • 2017-11-02
  • 2016-09-16
  • 2020-09-02
  • 1970-01-01
  • 1970-01-01
  • 2022-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多