【发布时间】: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