使用row,col指示的矩阵的索引值

Mik*_*e T 24 indexing r matrix r-faq

这可能很容易解决.我有一个mat500行×335列的2D矩阵和一个dat120425行的data.frame.该data.frame dat有两列IJ,它是整数索引的行,列的mat.我想将值添加mat到行的行中dat.

这是我的概念失败:

> dat$matval <- mat[dat$I, dat$J]
Error: cannot allocate vector of length 1617278737
Run Code Online (Sandbox Code Playgroud)

(我在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 ...
Run Code Online (Sandbox Code Playgroud)

我期待着类似的东西int [1:100] 20 1 1 1 20 1 1 1 1 1 ....使用行,列索引索引2D矩阵以获取值的正确方法是什么?

42-*_*42- 39

几乎.需要提供"["作为两列矩阵:

dat$matval <- mat[ cbind(dat$I, dat$J) ] # should do it.
Run Code Online (Sandbox Code Playgroud)

有一点需要注意:虽然这也适用于数据帧,但它们首先被强制转换为矩阵类,如果有的话,它们是非数字的,整个矩阵成为"最低分母"类.

  • @ gsk3:查看参数部分?"["下的"...".当寻址阵列或矩阵时,矩阵必须具有与被寻址对象具有维度相同的列数.该帮助页面上还有一些示例. (3认同)

Tom*_*mmy 10

使用矩阵索引为DWin建议当然更清晰,但出于某些奇怪的原因,使用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
Run Code Online (Sandbox Code Playgroud)

dat$I + (dat$J-1L)*nrow(m)部分将二维指数转换为一维指数.这1L是指定整数而不是double值的方法.这避免了一些强制.

...我也试过gsk3的基于应用的解决方案.它虽然慢了近500倍:

system.time( apply( dat, 1, function(x,mat) mat[ x[1], x[2] ], mat=mat ) ) # 212
Run Code Online (Sandbox Code Playgroud)