尝试在r代码中实现独占完全连接。
实现了以下代码,该代码正常工作但是正确的方法,因为过滤器填充了很多条件。由于这是示例代码并没有添加很多列,但实时情况下我们有很多列,因此将列添加到过滤会使事情变得困难。
那么还有其他更好的方法吗?
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)))
输出:
答案 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_vars
和dplyr
。
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