【问题标题】:R: How to efficiently find out whether data.frame A is contained in data.frame B?R:如何有效地找出data.frame A是否包含在data.frame B中?
【发布时间】:2015-03-30 21:18:51
【问题描述】:

为了找出数据框 df.a 是否是数据框 df.b 的子集,我做了以下操作:

df.a <- data.frame( x=1:5, y=6:10 )
df.b <- data.frame( x=1:7, y=6:12 )
inds.x <- as.integer( lapply( df.a$x, function(x) which(df.b$x == x) ))
inds.y <- as.integer( lapply( df.a$y, function(y) which(df.b$y == y) ))
identical( inds.x, inds.y )

最后一行给出了TRUE,因此df.a包含在df.b中。

现在我想知道是否有更优雅——可能更有效——的方式来回答这个问题?

此任务还可以轻松扩展,以查找两个给定数据帧之间的交集,可能仅基于列的子集。

我们将不胜感激。

【问题讨论】:

  • 可能是all(mapply("%in%", df.a, df.b))?当然,假设它们具有相同顺序的相同列。或者对于列子集和正确列顺序的更安全的方法可能是cols &lt;- c("x", "y") ; all(mapply("%in%", df.a[cols], df.b[cols]))
  • 识别配对是否重要? data.frame(a=1:4, b=5:8)data.frame(a=8:1, b=1:8) 的子集。我会说不,但意见可能会有所不同。
  • @DavidArenburg,我认为这可能会因c(2, 2) 包含在c(2) 中的情况而变得复杂?
  • 假设数据框行中没有重复项,您可以使用 dplyr 包中的 mergeinner_join
  • 我认为dplyr::semi_join 可以为所欲为。 df.a &lt;- data.frame( x=c(1:5,1), y=c(6:10,6) ); df.b &lt;- data.frame( x=1:7, y=6:12 ); df.c &lt;- data.frame( x=c(1:7, 1), y= c(6:12, 6) )semi_join(df.b, df.a) 失败但 semi_join(df.c, df.a) 成功(直到规范排序)

标签: r dataframe subset set-intersection


【解决方案1】:

我将冒险猜测答案。

我认为来自dplyrsemi_join 会做你想做的事,即使考虑到重复的行。

首先记下帮助文件?semi_join

返回 x 中在 y 中有匹配值的所有行,只保留 x 中的列。

半连接与内连接不同,因为内连接 join 将为每个匹配的 y 行返回一行 x, 半连接将在哪里 永远不要重复 x 行。

好的,这表明以下应该正确失败:

df.a <- data.frame( x=c(1:5,1), y=c(6:10,6) )
df.b <- data.frame( x=1:7, y=6:12 )
identical(semi_join(df.b, df.a),  semi_join(df.a, df.a))

给出FALSE,正如预期的那样

> semi_join(df.b, df.a)
Joining by: c("x", "y")
  x  y
1 1  6
2 2  7
3 3  8
4 4  9
5 5 10

但是,以下应该通过:

df.c <- data.frame( x=c(1:7, 1), y= c(6:12, 6) )
identical(semi_join(df.c, df.a), semi_join(df.a, df.a))

确实如此,给TRUE

需要第二个semi_join(df.a, df.a) 才能对df.a 进行规范排序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 2019-09-03
    • 2017-08-16
    相关资源
    最近更新 更多