独家完全加入r

时间:2017-12-14 17:35:37

标签: r join

尝试在r代码中实现独占完全连接。

Exclusive Full Join Image.

实现了以下代码,该代码正常工作但是正确的方法,因为过滤器填充了很多条件。由于这是示例代码并没有添加很多列,但实时情况下我们有很多列,因此将列添加到过滤会使事情变得困难。

那么还有其他更好的方法吗?

library(tidyverse)

persons = data.frame(
  name = c("Ponting", "Clarke", "Dave", "Bevan"),
  age = c(24, 32, 26, 29),
  col1 = c(1,2,3,4),
  col2 = c("a", "z", "h", "p")
)

person_sports = data.frame(
  name = c("Ponting", "Dave", "Roshan"),
  sports = c("soccer", "tennis", "boxing"),
  rank = c(8, 4, 1),
  col3 = c("usa", "australia", "england"),
  col4 = c("a", "f1", "z2")
)

persons %>% full_join(person_sports, by = c("name")) %>%
  filter((is.na(age) & is.na(col1) & is.na(col2)) | (is.na(sports) & is.na(rank) & is.na(col3) & is.na(col4)))

输出:

enter image description here

1 个答案:

答案 0 :(得分:2)

尝试使用complete.cases。这将返回一个TRUE / FALSE向量,其中FALSE表示在至少一列的给定行上找到NA。

persons %>% full_join(person_sports, by = c("name")) %>% .[!complete.cases(.), ]
#     name age col1 col2 sports rank    col3 col4
# 2 Clarke  32    2    z   <NA>   NA    <NA> <NA>
# 4  Bevan  29    4    p   <NA>   NA    <NA> <NA>
# 5 Roshan  NA   NA <NA> boxing    1 england   z2

作为替代方案,与上述方法类似,请使用filter_all包中的any_varsdplyr

persons %>% full_join(person_sports, by = c("name")) %>% filter_all(any_vars(is.na(.)))
#     name age col1 col2 sports rank    col3 col4
# 1 Clarke  32    2    z   <NA>   NA    <NA> <NA>
# 2  Bevan  29    4    p   <NA>   NA    <NA> <NA>
# 3 Roshan  NA   NA <NA> boxing    1 england   z2

最后,既然您提到您的实际数据集要大得多,您可能希望与data.table解决方案进行比较,看看哪些解决方案在您的真实数据中效果最佳。

library(data.table)
setDT(persons)
setDT(person_sports)

merge(persons, person_sports, by = "name", all = TRUE) %>% .[!complete.cases(.)]
#      name age col1 col2 sports rank    col3 col4
# 1:  Bevan  29    4    p     NA   NA      NA   NA
# 2: Clarke  32    2    z     NA   NA      NA   NA
# 3: Roshan  NA   NA   NA boxing    1 england   z2