我有一个包含三列的数据框,第二个包含两列。
df1 <- data.frame(X1 = c('A', 'A', 'A', 'A', 'A', 'A', 'B'),
X2 = c('B', 'B', 'B', 'C', 'C', 'D', 'C'),
X3 = c('C', 'D', 'E', 'D', 'E', 'E', 'D'))
df2 <- data.frame(X1 = c('A', 'A'),
X2 = c('B', 'D'))
问题:
df1
中找到包含 df2
行的所有元素的行?即 df1
的第 1:3 行包含 A
和 B
(df2
的第一行)。我希望删除包含 df1
行的两个元素的任何 df2
行。因此,在示例中,我想删除 df1
的第 1、2、3、4 和 6 行,因为它们包括 A
和 B
OR A
和 {{1 }}。D
的每一行的行数而不循环的方法?即 df2
第 1 行的计数为 3,第 2 行的计数为 3。答案 0 :(得分:2)
这是使用 outer
+ intersect
mat <- lengths(
outer(
asplit(df1, 1),
asplit(df2, 1),
Vectorize(intersect)
)
) >= ncol(df2)
你会得到
> subset(df1, !rowSums(mat))
X1 X2 X3
5 A C E
7 B C D
> within(df2, cnt <- colSums(mat))
X1 X2 cnt
1 A B 3
2 A D 3
asplit
按行拆分数据框outer
生成来自 df1
和 df2
的所有行组合intersect
给出两个数据框中行的相交元素subset
选择公共元素少于一个的行答案 1 :(得分:1)
使用应用:
df1[ !apply(df1, 1, function(i) any(apply(df2, 1, function(j) all(j %in% i)))), ]
# X1 X2 X3
# 5 A C E
# 7 B C D
对 df2 匹配计数执行类似的循环:
cbind(df2,
cnt = apply(df2, 1, function(i) sum(apply(df1, 1, function(j) all(i %in% j)))))
# X1 X2 cnt
# 1 A B 3
# 2 A D 3
答案 2 :(得分:0)
你需要以某种方式循环。以下是使用 dplyr
和 purrr
执行此操作的一种方法:
1.
for(iRow in seq_len(nrow(df2))){
df1 <- df1 %>%
rowwise() %>%
filter(!all(as.character(df2[iRow,]) %in% c_across(everything())))
}
2.
df2 %>%
rowwise() %>%
mutate(n = sum(map_int(transpose(df1), ~all(c_across(everything()) %in% .x))))
请务必在第一部分之前完成第二部分,因为第一部分删除了行。您还可以首先检测要为 df2
的每一行删除哪些行。通过这种方式,您可以计算它们,然后将其删除。
df2 <- df2 %>%
rowwise() %>%
mutate(
indices = list(which(map_lgl(transpose(df1), ~all(c_across(everything()) %in% .x))))
) %>%
ungroup() %>%
mutate(n = map_int(indices, length))
df1 <- df2[["indices"]] %>%
unlist() %>%
unique() %>%
"*"(-1) %>%
df1[.,]
df2 <- df2 %>% select(-indices)