-->

使用行从矩阵指数值,山坳indicies(Index values from a matrix us

2019-09-29 08:16发布

这可能是简单的解决。 我有一个2D矩阵mat用500行×335列,和一个data.frame dat与120425点的行。 该data.frame dat有两列IJ ,这是整数索引的行,从塔mat 。 我想从添加值mat到的行dat

这里是我的概念失败:

> dat$matval <- mat[dat$I, dat$J]
Error: cannot allocate vector of length 1617278737

(我在Win32,使用R 2.13.1)。 挖一个深一点,我看到我滥用矩阵索引,因为它看来,我只得到的子矩阵mat ,而不是值的一维数组如我所料,即:

> str(mat[dat$I[1:100], dat$J[1:100]])
 int [1:100, 1:100] 20 1 1 1 20 1 1 1 1 1 ...

我期待像int [1:100] 20 1 1 1 20 1 1 1 1 1 ... 。 什么是指数的正确方法使用行,列的索引来获取值的二维矩阵?

Answer 1:

几乎。 需要将提供给“[”作为一个两列的矩阵:

dat$matval <- mat[ cbind(dat$I, dat$J) ] # should do it.

有一个警告:虽然这也适用于dataframes,它们首先被强制转换矩阵级,如果任何的非数字,整个矩阵变成“最低分母”级。



Answer 2:

使用矩阵指数迪文建议当然是干净多了,但对于一些奇怪的原因做它使用1-d指数人工实际上是略快:

# Huge sample data
mat <- matrix(sin(1:1e7), ncol=1000)
dat <- data.frame(I=sample.int(nrow(mat), 1e7, rep=T), 
                  J=sample.int(ncol(mat), 1e7, rep=T))

system.time( x <- mat[cbind(dat$I, dat$J)] )     # 0.51 seconds
system.time( mat[dat$I + (dat$J-1L)*nrow(mat)] ) # 0.44 seconds

所述dat$I + (dat$J-1L)*nrow(m)部转动2- d指数成1- d的。 在1L是指定一个整数,而不是双价值的方式。 这样就避免了一些强制转换。

......我也试过GSK3的应用为基础的解决方案。 这几乎是500倍速度较慢,但​​:

system.time( apply( dat, 1, function(x,mat) mat[ x[1], x[2] ], mat=mat ) ) # 212


Answer 3:

下面是一个使用一个班轮apply的基于行的操作

> dat <- as.data.frame(matrix(rep(seq(4),4),ncol=2))
> colnames(dat) <- c('I','J')
> dat
   I  J
1  1  1
2  2  2
3  3  3
4  4  4
5  1  1
6  2  2
7  3  3
8  4  4
> mat <- matrix(seq(16),ncol=4)
> mat
     [,1] [,2] [,3] [,4]
[1,]    1    5    9   13
[2,]    2    6   10   14
[3,]    3    7   11   15
[4,]    4    8   12   16

> dat$K <- apply( dat, 1, function(x,mat) mat[ x[1], x[2] ], mat=mat )
> dat
  I J  K
1 1 1  1
2 2 2  6
3 3 3 11
4 4 4 16
5 1 1  1
6 2 2  6
7 3 3 11
8 4 4 16


Answer 4:

n <- 10
mat <- cor(matrix(rnorm(n*n),n,n))
ix <- matrix(NA,n*(n-1)/2,2)
k<-0
for (i in 1:(n-1)){
    for (j in (i+1):n){
    k <- k+1
    ix[k,1]<-i
    ix[k,2]<-j
    }
}
o <- rep(NA,nrow(ix))
o <- mat[ix]
out <- cbind(ix,o)


文章来源: Index values from a matrix using row, col indicies