Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将列表匹配到R中的矩阵行_R_List_Matrix - Fatal编程技术网

将列表匹配到R中的矩阵行

将列表匹配到R中的矩阵行,r,list,matrix,R,List,Matrix,“a”是一个列表,“b”是一个矩阵 a<-list(matrix(c(0,2,0,1,0,2,0,0,1,0,0,0,0,0,2,2),4), matrix(c(0,1,0,0,0,1,1,0,0,0,0,0),3), matrix(c(0,0,0,0,2,0,1,0,0,0,0,0,2,0,2,1,0,1,1,0),5)) b<-matrix(c(2,2,1,1,1,2,1,2,1,1,2,1,1,1,1,1,1,2,2,2,1,2,1,1),6)

“a”是一个列表,“b”是一个矩阵

a<-list(matrix(c(0,2,0,1,0,2,0,0,1,0,0,0,0,0,2,2),4), 
        matrix(c(0,1,0,0,0,1,1,0,0,0,0,0),3),
        matrix(c(0,0,0,0,2,0,1,0,0,0,0,0,2,0,2,1,0,1,1,0),5))
b<-matrix(c(2,2,1,1,1,2,1,2,1,1,2,1,1,1,1,1,1,2,2,2,1,2,1,1),6) 

> a
[[1]]
     [,1] [,2] [,3] [,4]
[1,]    0    0    1    0
[2,]    2    2    0    0
[3,]    0    0    0    2
[4,]    1    0    0    2

[[2]]
     [,1] [,2] [,3] [,4]
[1,]    0    0    1    0
[2,]    1    0    0    0
[3,]    0    1    0    0

[[3]]
     [,1] [,2] [,3] [,4]
[1,]    0    0    0    1
[2,]    0    1    0    0
[3,]    0    0    2    1
[4,]    0    0    0    1
[5,]    2    0    2    0

> b
     [,1] [,2] [,3] [,4]
[1,]    2    1    1    2
[2,]    2    2    1    2
[3,]    1    1    1    1
[4,]    1    1    1    2
[5,]    1    2    1    1
[6,]    2    1    2    1
我们可以看到第一行的非零数字是1,它位于第三行,它可以匹配矩阵“b”的1-5行,第二行的非零数字是1,它位于这一行的第一行,它可以匹配矩阵“b”的3-5行,第三行的非零数字是1,它位于该行的第二位,可以匹配矩阵“b”的3-4行。因此,只有矩阵“b”的第3行或第4行可以匹配此对象中的所有行,因此输出结果为“3 4”

我的代码如下:

temp<-Map(function(y) t(y), Map(function(a) 
           apply(a,1,function(x){
                 apply(b,1, function(y) identical(x[x!=0],y[x!=0]))}),a))
lapply(temp, function(a) which(apply(a,2,prod)==1))
[[1]]
integer(0)

[[2]]
[1] 3 4

[[3]]
[1] 6

是的。但我想知道是否有更快捷的代码来处理这个问题

你对你想要什么以及你可能的矩阵是什么样子的解释真的不清楚。根据我的推断,您希望匹配
b
中的行号,该行号匹配
a
中矩阵每列中唯一的非零编号。如果是这样,这里有一个更简单的选择:

lapply(a, function(x){    # loop across the matrices in a
    x[x == 0] <- NA       # replace 0s with NA
    which(apply(b, 1, function(y){            # loop across the rows of b, trying to match
        all(y == colMeans(x, na.rm = TRUE))   # the rows of b with the colmeans of x
    }))
})
# [[1]]
# [1] 2
# 
# [[2]]
# [1] 5
# 
# [[3]]
# [1] 6
lappy(a,函数(x){#在a中的矩阵上循环

x[x==0]有几个列,并试图利用具有>1个唯一值或没有非零值的列来减少计算:

ff = function(a, b)
{
    i = seq_len(nrow(b))  #starting candidate matches
    for(j in seq_len(ncol(a))) {
        aj = a[, j]
        nzaj = aj[aj != 0L]
        if(!length(nzaj)) next  #if all(a[, j] == 0) save some operations
        if(sum(tabulate(nzaj) > 0L) > 1L) return(integer())  #if no unique values in a column break looping 
        i = i[b[i, j] == nzaj[[1L]]]  #update candidate matches
    }

    return(i)
}
lapply(a, function(x) ff(x, b))
#[[1]]
#integer(0)
#
#[[2]]
#[1] 3 4
#
#[[3]]
#[1] 6
使用实际尺寸的数据:

set.seed(911)
a2 = replicate(300L, matrix(sample(0:3, 20 * 5, TRUE, c(0.97, 0.01, 0.01, 0.01)), 20, 5), simplify = FALSE)
b2 = matrix(sample(1:3, 15 * 5, TRUE), 15, 5)
identical(OP(a2, b2), lapply(a2, function(x) ff(x, b2)))
#[1] TRUE
microbenchmark::microbenchmark(OP(a2, b2), lapply(a2, function(x) ff(x, b2)), times = 50)
#Unit: milliseconds
#                              expr        min         lq       mean     median         uq       max neval cld
#                        OP(a2, b2) 686.961815 730.840732 760.029859 753.790094 785.310056 863.04577    50   b
# lapply(a2, function(x) ff(x, b2))   8.110542   8.450888   9.381802   8.949924   9.872826  15.51568    50  a
OP
是:

OP = function (a, b) 
{
    temp = Map(function(y) t(y), Map(function(a) apply(a, 1, 
        function(x) {
            apply(b, 1, function(y) identical(x[x != 0], y[x != 
                0]))
        }), a))
    lapply(temp, function(x) which(apply(x, 2, prod) == 1))
}

实际上元素[3,4]不匹配…@为什么?它是匹配的。“a”的第一个对象中的所有非零元素匹配矩阵“b”第二行的对应位置,“a”的第二个对象中的所有非零元素匹配矩阵“b”第五行的对应位置,并且“a”的第三个对象中的所有非零元素与矩阵“b”的第六行的相应位置匹配。您的实际数据的维度是什么?@alexis_laz“a”有300个对象(每个对象是一个矩阵(第20X5轮)),“b”是一个15行的矩阵。如果你在同一列中有两个非零的数字,比如在
a[[1]]
?嗨,@alistaire,如果一列中的元素在列表“a”的对象中都是0,那么你的答案会出错,谢谢。看看“a”的第二个对象中的这种情况,例如,a[[2]]中的每一行可以与矩阵“b”中的第3行和第4行匹配,因为所有非零元素都可以与“b”的第3行或第4行中的相应位置(列)匹配。但是,使用您的代码,结果是“整数(0)”因为你认为所有的列都包含非零元素。你需要完全排列你需要遵循的逻辑。更新例子是好的,但是你仍然没有解释它应该如何评估到期望的结果,让读者猜测。是的,有点难以表达,我认为你推断的是正确的。
OP = function (a, b) 
{
    temp = Map(function(y) t(y), Map(function(a) apply(a, 1, 
        function(x) {
            apply(b, 1, function(y) identical(x[x != 0], y[x != 
                0]))
        }), a))
    lapply(temp, function(x) which(apply(x, 2, prod) == 1))
}