r - 使用大矩阵操作

标签 r r-bigmemory bigdata

我必须使用 big.matrix 对象,但无法计算某些函数。让我们考虑以下大矩阵:

# create big.matrix object
x <- as.big.matrix(
      matrix( sample(1:10, 20, replace=TRUE), 5, 4,
           dimnames=list( NULL, c("a", "b", "c", "d")) ) )

> x
An object of class "big.matrix"
Slot "address":
<pointer: 0x00000000141beee0>

对应的矩阵对象为:

# create matrix object

x2<-x[,]

> x2
     a b  c  d
[1,] 6 9  5  3
[2,] 3 6 10  8
[3,] 7 1  2  8
[4,] 7 8  4 10
[5,] 6 3  6  4

如果我使用矩阵对象计算此操作,它会起作用:

sqrt(slam::col_sums(x2*x2))

> sqrt(slam::col_sums(x2*x2))
       a        b        c        d 
13.37909 13.82027 13.45362 15.90597 

如果我使用 big.matrix 对象(实际上我必须使用它),它就不起作用:

sqrt(biganalytics::colsum(x*x))

问题 2:* 运算(创建矩阵每个元素的平方),会产生错误:

Error in x * x : non-numeric argument transformed into binary operator

和 sqrt 函数,它会产生错误:

Error in sqrt(x) : non-numeric argument to mathematical function.

如何使用 big.matrix 对象计算此操作?

最佳答案

通过 big.matrix 对象,我发现了 2 个提供良好性能的解决方案:

  • 根据您的具体需要在 Rcpp 中编写一个函数。在这里,两个嵌套的 for 循环就可以解决问题。然而,您无法重新编码所需的所有内容。
  • big.matrix 的列 block 使用 R 函数并聚合结果。它很容易做到并且仅使用 R 代码。

就您而言,列数增加 10,000 倍:

require(bigmemory)

x <- as.big.matrix(
  matrix( sample(1:10, 20000, replace=TRUE), 5, 40000,
          dimnames=list( NULL, rep(c("a", "b", "c", "d"), 10000) ) ) )

print(system.time(
  true <- sqrt(colSums(x[,]^2))
))

print(system.time(
  test1 <- biganalytics::apply(x, 2, function(x) {sqrt(sum(x^2))})
))
print(all.equal(test1, true))

因此,colSums 速度非常快,但需要 RAM 中的所有矩阵,而 biganalytics::apply 速度较慢,但​​内存效率高。一种折衷方案是使用这样的东西:

CutBySize <- function(m, block.size, nb = ceiling(m / block.size)) {
  int <- m / nb

  upper <- round(1:nb * int)
  lower <- c(1, upper[-nb] + 1)
  size <- c(upper[1], diff(upper))

  cbind(lower, upper, size)
}

seq2 <- function(lims) seq(lims["lower"], lims["upper"])

require(foreach)
big_aggregate <- function(X, FUN, .combine, block.size = 1e3) {
  intervals <- CutBySize(ncol(X), block.size)

  foreach(k = 1:nrow(intervals), .combine = .combine) %do% {
    FUN(X[, seq2(intervals[k, ])])
  }
}

print(system.time(
  test2 <- big_aggregate(x, function(X) sqrt(colSums(X^2)), .combine = 'c')
))
print(all.equal(test2, true))

编辑:现在已在包bigstatsr中实现:

print(system.time(
  test2 <- bigstatsr::big_apply(x, a.FUN = function(X, ind) {
    sqrt(colSums(X[, ind]^2))
  }, a.combine = 'c')
))
print(all.equal(test2, true))

关于r - 使用大矩阵操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42111876/

相关文章:

r - 从 R 中的 bestglm 包中提取最佳模型的公式

r - 如何在 R 中仅引用 write.csv/table 的列?

r - 如何将 2.8 GB gzipped (40 GB TSV) 文件批量读取到 R 中?

sql - 获得 10 个不同的项目以及相关任务的最新更新

r - 如何在不使用谷歌地图(图像)的情况下在 map 上绘制数据?

r - 在一系列日期中识别第三个星期五

R bigmemory attach.big.matrix 对于非常宽的矩阵来说非常慢

r - 大矩阵的线性回归

java - 如何通过网络运行Hadoop程序

twitter-bootstrap - 大数据的最佳实践?