r语言 - 查找一个数据框中包含另一个数据框中一行元素的行



我有一个包含三列的数据框,第二个包含两列的数据框。

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'))

问题:

  1. 我如何找到df1中包含df2一行的所有元素的行?即df1的第1:3行同时包含AB(df2的第一行)。我希望删除df1的任何行,其中包含df2行的两个元素。因此,在示例中,我想删除df1的第1,2,3,4和6行,因为这些行包括ABAD
  2. 是否有一种快速的方法来计算df2的每一行的行数而不循环?即df2第1行计数为3,第2行计数为3。

这是使用outer+intersect的基础R选项

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生成df1df2的所有行组合
  • intersect给出了来自两个数据帧的行相交元素
  • subset选择少于一个公共元素的行

Usingapply:

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

你需要以某种方式循环。下面是使用dplyrpurrr的一种方法:

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)

相关内容

  • 没有找到相关文章

最新更新