R
中的value matching function非常有用。但根据我的理解,它不足以支持两个或高维输入。
例如,假设x
和y
是具有相同列数的矩阵,我希望将x
行与y
行匹配。 'R'函数调用match(x,y)
不会这样做。列表的输入也出现相同的不足。
我已经实现了我自己的版本matchMat(xMat, yMat)
(附在下面),但我想知道你是什么解决了这个任务。
matchMat = function(xMat, uMat, dimn=1) {
ind = rep(-1, dim(xMat)[dimn])
id = 1 : dim(uMat)[dimn]
for (i in id) {
e = utilSubMat(i, uMat, dimn)
isMatch = matchVect(e, xMat, dimn)
ind[isMatch] = i
}
return(ind)
}
matchVect = function(v, xMat, dimn) {
apply(xMat, dimn, function(e) {
tf = e == v
all(tf)
})
}
unittest_matchMat = function() {
dimn = 1
uMat = matrix(c(1, 2, 2, 3, 3, 4, 4, 5), ncol=2, byrow=T)
ind = sample(dim(uMat)[1], 10, replace=T)
print(ind)
xMat = uMat[ind, ]
rst = matchMat(xMat, uMat, dimn)
print(rst)
stopifnot(all(ind == rst))
xMat2 = rbind(c(999, 999), xMat, c(888, 888))
rst2 = matchMat(xMat2, uMat, dimn)
print(rst2)
stopifnot(all(c(-1, ind, -1) == rst2))
print('pass!')
}
答案 0 :(得分:11)
match
将用于list
个原子向量。因此,要将一个矩阵的行匹配到另一个矩阵,您可以这样做:
match(data.frame(t(x)), data.frame(t(y)))
t
将行转置为列,然后data.frame
在转置矩阵中创建list
列。
答案 1 :(得分:1)
您可以在不使用任何功能的情况下执行此操作:
假设adj1
是3*3
矩阵, colnames 和 row.names 都是c('V1','V2','V3')
和vec1
是您希望矩阵转换为的顺序:
vec1 <- c('V2','V3','V1')
您只需使用以下代码:
adj1[vec1,vec1]
这将是你的魔力。
干杯!
答案 2 :(得分:1)
包row.match
中的函数prodlim
允许您识别一个矩阵中的行,这些行也在另一个矩阵中找到(相同)。非常方便易用。
library(prodlim)
row.match(x,y)
答案 3 :(得分:0)
您可以使用apply
:
z <- apply(x, 1, function(a) apply(y, 1, function(b) all(a==b)))
这将生成一个包含nrow(x)
行和nrow(y)
列的矩阵,其条目标记匹配的索引。
答案 4 :(得分:0)
您可以使用asplit
创建一个list
,供比赛使用。但是手册说列表被转换为字符向量,并且匹配列表可能非常缓慢,最好在简单情况下避免。
match(asplit(x, 1), asplit(y, 1))
#[1] NA 1 2
因此可以选择使用interaction
或paste
。
match(interaction(data.frame(x)), interaction(data.frame(y)))
#[1] NA 1 2
match(apply(x, 1, paste, collapse =" "), apply(y, 1, paste, collapse =" "))
#[1] NA 1 2
数据:
(x <- matrix(1:9, 3))
# [,1] [,2] [,3]
#[1,] 1 4 7
#[2,] 2 5 8
#[3,] 3 6 9
(y <- matrix(2:10, 3))
# [,1] [,2] [,3]
#[1,] 2 5 8
#[2,] 3 6 9
#[3,] 4 7 10