基于存储在独立有序向量中的值对来子集数据帧

sri*_*amn 7 r subset

我有一个R数据帧,我需要从中分配数据.子集将基于数据帧中的两列.例如:

A <- c(1,2,3,3,5,1)
B <- c(6,7,8,9,8,8)
Value <- c(9,5,2,1,2,2)
DATA <- data.frame(A,B,Value)
Run Code Online (Sandbox Code Playgroud)

这就是DATA的样子

A B Value
1 6     9
2 7     5
3 8     2
3 9     1
5 8     2
1 8     2
Run Code Online (Sandbox Code Playgroud)

我想要那些(A,B)组合是(1,6)和(3,8)的数据行.这些对存储为A和B的单个(有序)向量:

AList <- c(1,3)
BList <- c(6,8)
Run Code Online (Sandbox Code Playgroud)

现在,我想通过比较基本子集数据如果某列存在于ALIST -B柱上在BList存在

DATA[(DATA$A %in% AList & DATA$B %in% BList),]
Run Code Online (Sandbox Code Playgroud)

子集化结果如下所示.除了价值对(1,6)和(3,8),我也得到(1,8).基本上,这个过滤器给了我AList和BList中所有组合的值对.如何将其限制为(1,6)和(3,8)?

A B Value
1 6     9
3 8     2
1 8     2
Run Code Online (Sandbox Code Playgroud)

这是我想要的结果:

A B Value
1 6     9
3 8     2
Run Code Online (Sandbox Code Playgroud)

sgi*_*ibb 7

你可以试试match哪个适当的nomatch论点:

sub <- match(DATA$A, AList, nomatch=-1) == match(DATA$B, BList, nomatch=-2)
sub
# [1]  TRUE FALSE  TRUE FALSE FALSE FALSE

DATA[sub,]
#  A B Value
#1 1 6     9
#3 3 8     2
Run Code Online (Sandbox Code Playgroud)

一个paste基础的方法也将是可能的:

sub <- paste(DATA$A, DATA$B, sep=":") %in% paste(AList, BList, sep=":")
sub
# [1]  TRUE FALSE  TRUE FALSE FALSE FALSE

DATA[sub,]
#  A B Value
#1 1 6     9
#3 3 8     2
Run Code Online (Sandbox Code Playgroud)


flo*_*del 7

这是一份工作merge:

KEYS <- data.frame(A = AList, B = BList)
merge(DATA, KEYS)

#   A B Value
# 1 1 6     9
# 2 3 8     2
Run Code Online (Sandbox Code Playgroud)

编辑:OP在下面的评论中表达了他对逻辑向量的偏好后,我会建议以下之一.

用途merge:

df.in.df <- function(x, y) {
  common.names <- intersect(names(x), names(y))
  idx <- seq_len(nrow(x))
  x <- x[common.names]
  y <- y[common.names]
  x <- transform(x, .row.idx = idx)
  idx %in% merge(x, y)$.row.idx
}
Run Code Online (Sandbox Code Playgroud)

或者interaction:

df.in.df <- function(x, y) {
  common.names <- intersect(names(x), names(y))
  interaction(x[common.names]) %in% interaction(y[common.names])
}
Run Code Online (Sandbox Code Playgroud)

在这两种情况下:

df.in.df(DATA, KEYS)
# [1] TRUE FALSE  TRUE FALSE FALSE FALSE
Run Code Online (Sandbox Code Playgroud)