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

在使用apply函数时,R\u提取正在使用的元素的行和列

  •  2
  • rm167  · 技术社区  · 6 年前

    使用时如何提取所用元素的行和列 apply

    mymatrix <- matrix(1:12, nrow=3, ncol=4)
    

    我想要一个函数

    apply(mymatrix, c(1,2), function (x) sum(x, row_number, col_number))
    

    哪里 row_number col_number 中所选元素的行号和列号 mymatrix . 请注意,我的函数比 sum 因此,一个健壮的解决方案是值得赞赏的。

    3 回复  |  直到 6 年前
        1
  •  3
  •   Maurits Evers    6 年前

    我不太清楚你想做什么,但我会用 for 在这里循环。

    matrix 这将是非常快的

    ret <- mymatrix
    for (i in 1:nrow(mymatrix))
        for (j in 1:ncol(mymatrix))
            ret[i, j] <- sum(mymatrix[i, j], i, j)
    #     [,1] [,2] [,3] [,4]
    #[1,]    3    7   11   15
    #[2,]    5    9   13   17
    #[3,]    7   11   15   19
    

    我很好奇,所以我跑了一条路 microbenchmark 200x300 矩阵。

    mymatrix <- matrix(1:600, nrow = 200, ncol = 300)
    library(microbenchmark)
    res <- microbenchmark(
        for_loop = {
            ret <- mymatrix
            for (i in 1:nrow(mymatrix))
                for (j in 1:ncol(mymatrix))
                    ret[i, j] <- sum(mymatrix[i, j], i, j)
        },
        expand_grid_mapply = {
            newResult<- mymatrix
            grid1 <- expand.grid(1:nrow(mymatrix),1:ncol(mymatrix))
            newResult[]<-
            mapply(function(row_number, col_number){ sum(mymatrix[row_number, col_number], row_number, col_number) },row_number = grid1$Var1, col_number = grid1$Var2 )
        },
        expand_grid_apply = {
            newResult<- mymatrix
            grid1 <- expand.grid(1:nrow(mymatrix),1:ncol(mymatrix))
            newResult[]<-
            apply(grid1, 1, function(x){ sum(mymatrix[x[1], x[2]], x[1], x[2]) })
        },
        double_sapply = {
            sapply(1:ncol(mymatrix), function (x) sapply(1:nrow(mymatrix), function (y) sum(mymatrix[y,x],x,y)))
        }
    )
    
    res
    #Unit: milliseconds
    #               expr       min        lq      mean    median       uq       max
    #           for_loop  41.42098  52.72281  56.86675  56.38992  59.1444  82.89455
    # expand_grid_mapply 126.98982 161.79123 183.04251 182.80331 196.1476 332.94854
    #  expand_grid_apply 295.73234 354.11661 375.39308 375.39932 391.6888 562.59317
    #      double_sapply  91.80607 111.29787 120.66075 120.37219 126.0292 230.85411
    
    library(ggplot2)
    autoplot(res)
    

    enter image description here

    基准分析2(含 expand.grid 外部 微基准 )

    grid1 <- expand.grid(1:nrow(mymatrix),1:ncol(mymatrix))
    res <- microbenchmark(
        for_loop = {
            ret <- mymatrix
            for (i in 1:nrow(mymatrix))
                for (j in 1:ncol(mymatrix))
                    ret[i, j] <- sum(mymatrix[i, j], i, j)
        },
        expand_grid_mapply = {
            newResult<- mymatrix
            newResult[]<-
            mapply(function(row_number, col_number){ sum(mymatrix[row_number, col_number], row_number, col_number) },row_number = grid1$Var1, col_number = grid1$Var2 )
        },
        expand_grid_apply = {
            newResult<- mymatrix
            newResult[]<-
            apply(grid1, 1, function(x){ sum(mymatrix[x[1], x[2]], x[1], x[2]) })
        }
    )
    
    res
    #Unit: milliseconds
    #               expr       min        lq      mean    median        uq      max
    #           for_loop  39.65599  54.52077  60.87034  59.19354  66.64983  95.7890
    # expand_grid_mapply 130.33573 167.68201 194.39764 186.82411 209.33490 400.9273
    #  expand_grid_apply 296.51983 373.41923 405.19549 403.36825 427.41728 597.6937
    
        2
  •  1
  •   Andre Elrico    6 年前

    [lsvm]?apply -家庭。

    在应用之前,必须创建当前行和列索引。 ?expand.grid .

    mymatrix <- matrix(1:12, nrow=3, ncol=4)
    newResult<- mymatrix
    
    grid1 <- expand.grid(1:nrow(mymatrix),1:ncol(mymatrix))
    
    newResult[]<-
    mapply(function(row_number, col_number){ sum(mymatrix[row_number, col_number], row_number, col_number) },row_number = grid1$Var1, col_number = grid1$Var2 )
    
    newResult
    
    #     [,1] [,2] [,3] [,4]
    #[1,]    3    7   11   15
    #[2,]    5    9   13   17
    #[3,]    7   11   15   19
    

    apply

    newResult[]<-    
    apply(grid1, 1, function(x){ sum(mymatrix[x[1], x[2]], x[1], x[2]) })
    
        3
  •  1
  •   Darren Tsai    6 年前

    这是我的想法 outer()

    第三个论点 FUN 可以是任意两个参数的函数。

    mymatrix <- matrix(1:12, nrow = 3, ncol = 4)
    nr <- nrow(mymatrix)
    nc <- ncol(mymatrix)
    mymatrix + outer(1:nr, 1:nc, FUN = "+")
    
         [,1] [,2] [,3] [,4]
    [1,]    3    7   11   15
    [2,]    5    9   13   17
    [3,]    7   11   15   19
    

    使用@Maurits Evers的基准代码:

    Unit: microseconds
         expr       min         lq      mean    median        uq        max
     for_loop 19963.203 22427.1630 25308.168 23811.855 25017.031 158341.678
        outer   848.247   949.3515  1054.944  1011.457  1059.217   1463.956
    

    另外,我还试着用 apply(X, c(1,2), function (x)) :

    (比其他答案慢一点)

    mymatrix <- matrix(1:12, nrow = 3, ncol = 4)
    n <- 1                                        # n = index of data
    nr <- nrow(mymatrix)
    apply(mymatrix, c(1,2), function (x) {
      row_number <- (n-1) %% nr + 1               # convert n to row number
      col_number <- (n-1) %/% nr + 1              # convert n to column number
      res <- sum(x, row_number, col_number)
      n <<- n + 1
      return(res)
    })
    
         [,1] [,2] [,3] [,4]
    [1,]    3    7   11   15
    [2,]    5    9   13   17
    [3,]    7   11   15   19