代码之家  ›  专栏  ›  技术社区  ›  poundifdef

在r中分配矩阵的最佳方法,空与否?

  •  33
  • poundifdef  · 技术社区  · 15 年前

    我正在编写R代码来创建一个正方形矩阵。所以我的方法是:

    1. 分配正确大小的矩阵
    2. 循环遍历矩阵的每个元素,并用适当的值填充它

    我的问题很简单:预先分配这个矩阵的最佳方法是什么?到目前为止,我有两种方法:

    > x <- matrix(data=NA,nrow=3,ncol=3)
    > x
         [,1] [,2] [,3]
    [1,]   NA   NA   NA
    [2,]   NA   NA   NA
    [3,]   NA   NA   NA
    

    > x <- list()
    > length(x) <- 3^2
    > dim(x) <- c(3,3)
    > x
         [,1] [,2] [,3]
    [1,] NULL NULL NULL
    [2,] NULL NULL NULL
    [3,] NULL NULL NULL
    

    据我所见,前者比后者更简洁。另外,前者用nas填充矩阵,后者用nulls填充。

    哪一种“更好”的方法可以做到这一点?在本例中,我将“更好”定义为“更好的性能”,因为这是统计计算,并且此操作将在大型数据集中进行。

    虽然前者更简洁,但理解起来并不容易,所以我觉得这两种方式都可以。

    另外,r中的na和null有什么区别?呐?空值告诉我“na”的长度是“1”,而空值的长度是“0”-但这里还有更多吗?还是最佳实践?这将影响我使用哪种方法来创建矩阵。

    3 回复  |  直到 8 年前
        1
  •  45
  •   Shane    15 年前

    当有疑问时,测试一下自己。第一种方法既简单又快速。

    > create.matrix <- function(size) {
    + x <- matrix()
    + length(x) <- size^2
    + dim(x) <- c(size,size)
    + x
    + }
    > 
    > system.time(x <- matrix(data=NA,nrow=10000,ncol=10000))
       user  system elapsed 
       4.59    0.23    4.84 
    > system.time(y <- create.matrix(size=10000))
       user  system elapsed 
       0.59    0.97   15.81 
    > identical(x,y)
    [1] TRUE
    

    关于na和null之间的差异:

    实际上有四个特殊常数。

    此外,还有四个特殊常量:空、na、inf和nan。

    空用于指示空对象。na用于缺少(_156;不可用_157;)数据值。inf表示无穷大,nan在ieee浮点运算中不是数字(例如,运算结果分别为1/0和0/0)。

    你可以在里面读更多 the R manual on language definition .

        2
  •  4
  •   David Marx    10 年前

    根据 this article 我们可以做得比预先分配更好 NA 通过预分配 NA_real_ . 从文章中:

    一旦为“x”中的任何单元格分配一个数值,则在分配新值时,必须首先将矩阵强制为数值。最初分配的逻辑矩阵是徒劳的,只是为垃圾收集器添加了不必要的内存占用和额外的工作。 相反,使用na_real_uu(或na_integer_u for integer)分配它。

    如建议:让我们测试一下。

    testfloat = function(mat){
      n=nrow(mat)
      for(i in 1:n){
        mat[i,] = 1.2
      }
    }
    
    >system.time(testfloat(matrix(data=NA,nrow=1e4,ncol=1e4)))
    user  system elapsed 
    3.08    0.24    3.32 
    > system.time(testfloat(matrix(data=NA_real_,nrow=1e4,ncol=1e4)))
    user  system elapsed 
    2.91    0.23    3.14 
    

    对于整数:

    testint = function(mat){
      n=nrow(mat)
      for(i in 1:n){
        mat[i,] = 3
      }
    }
    
    > system.time(testint(matrix(data=NA,nrow=1e4,ncol=1e4)))
    user  system elapsed 
    2.96    0.29    3.31 
    > system.time(testint(matrix(data=NA_integer_,nrow=1e4,ncol=1e4)))
    user  system elapsed 
    2.92    0.35    3.28 
    

    在我的测试用例中差异很小,但确实存在。

        3
  •  0
  •   Odysseus Ithaca    8 年前
    rows<-3
    cols<-3    
    x<-rep(NA, rows*cols)
    x1 <- matrix(x,nrow=rows,ncol=cols)