我有一个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)
这就是DATA的样子
A B Value
1 6 9
2 7 5
3 8 2
3 9 1
5 8 2
1 8 2
我想要(A,B)组合为(1,6)和(3,8)的那些数据行。这些对存储为A和B的单个(有序)向量:
AList <- c(1,3)
BList <- c(6,8)
现在,我试图通过比较AList中是否存在A列 AND B列中存在BList
来基本上对数据进行子集化DATA[(DATA$A %in% AList & DATA$B %in% BList),]
子集化结果如下所示。除了价值对(1,6)和(3,8),我也得到(1,8)。基本上,这个过滤器给了我AList和BList中所有组合的值对。如何将其限制为(1,6)和(3,8)?
A B Value
1 6 9
3 8 2
1 8 2
这是我想要的结果:
A B Value
1 6 9
3 8 2
答案 0 :(得分: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
基于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
答案 1 :(得分:7)
这是merge
的作业:
KEYS <- data.frame(A = AList, B = BList)
merge(DATA, KEYS)
# A B Value
# 1 1 6 9
# 2 3 8 2
编辑: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
}
或interaction
:
df.in.df <- function(x, y) {
common.names <- intersect(names(x), names(y))
interaction(x[common.names]) %in% interaction(y[common.names])
}
在这两种情况下:
df.in.df(DATA, KEYS)
# [1] TRUE FALSE TRUE FALSE FALSE FALSE