使用公式(而不是函数)指定map2()的选项

时间:2018-07-21 15:39:43

标签: r iteration purrr

举例来说,我正在尝试使用purrr :: map2()在向量上迭代rnorm(),我想指定选项 n sd 但不是平均

使用“公式”方式,我可以这样做:

len <- c(1, 3, 10); sigma <- c(1, 1, 10)
set.seed(123)
map2(len, sigma, ~rnorm(n = .x, sd = .y))

但是可以通过方式指定 n sd 而不指定平均值吗?如果我执行以下操作,则会在平均值中填写“ sigma”,因为平均值是rmrm()中 n 之后的下一个选项。

set.seed(123)
map2(len, sigma, rnorm) 

我可以指定平均值为0,以便将“ sigma”应用于 sd ,如下所示:

set.seed(123)
map2(len, sigma, rnorm, mean = 0) 

但是,如果我想将平均值保留为默认值(不指定它)并且仍对 sd 应用“ sigma”怎么办?如上所示,如果我使用“函数”方法,是否可以执行类似.x / .y的方法。

对不起,罗word。非常感谢!

2 个答案:

答案 0 :(得分:4)

否,因为您必须手动将数据定向到除第一个参数之外的其他参数。这是基数R的Map的优点之一,它可以使用命名参数进行迭代:

library(purrr)

len <- c(1, 3, 10) 
sigma <- c(1, 1, 10)

set.seed(123)
map2(len, sigma, ~rnorm(n = .x, sd = .y)) %>% str()
#> List of 3
#>  $ : num -0.56
#>  $ : num [1:3] -0.2302 1.5587 0.0705
#>  $ : num [1:10] 1.29 17.15 4.61 -12.65 -6.87 ...

set.seed(123)
Map(rnorm, n = len, sd = sigma) %>% str()
#> List of 3
#>  $ : num -0.56
#>  $ : num [1:3] -0.2302 1.5587 0.0705
#>  $ : num [1:10] 1.29 17.15 4.61 -12.65 -6.87 ...

您无法在map2中执行相同的操作,因为输入参数分别命名为.x.y,而Map却将{{1 }}。

答案 1 :(得分:3)

除了使用pmap之外,另一个选择是使用set.seed(123) a <- map2(len, sigma, ~rnorm(n = .x, sd = .y)) set.seed(123) input <- list(n = len, sd = sigma) b <- pmap(input, rnorm) identical(a, b) # [1] TRUE 。这要求您将输入内容放在列表中。

// Clear Layers
    this.getLayer1GC().clearRect(0, 0, this.getLayer1GC().getCanvas().getWidth(),
                this.getLayer1GC().getCanvas().getHeight());

    this.getLayer2GC().clearRect(0, 0, this.getLayer2GC().getCanvas().getWidth(),
                this.getLayer2GC().getCanvas().getHeight());

    int index = 0;

    int tileSize = 64 * Engine.SCALE; // 128x128

    int startCol = Math.max(0, (int) (Engine.camera.xView / tileSize));

    int endCol = Math.min(this.width,
            (int) ((Engine.camera.xView + Engine.camera.wView) / tileSize) + 1);

    int startRow = Math.max(0, (int) (Engine.camera.yView / tileSize));

    int endRow = Math.min(this.height,
            (int) ((Engine.camera.yView + Engine.camera.hView) / tileSize) + 1);

    int tileX, tileY, indexLayer1, indexLayer2;

    for (int c = startCol; c < endCol; c++) {

        for (int r = startRow; r < endRow; r++) {

            // Tile Index
            index = this.tileManager.getTileIndex(c, r, this.width);

            // Tile Coordinates
            tileX = (int) (c * tileSize - Engine.camera.xView);
            tileY = (int) (r * tileSize - Engine.camera.yView);

            // Cache Tileset Images
            indexLayer1 = this.layer1.tileArray[index];
            indexLayer2 = this.layer2.tileArray[index];

            // Layer 1
            if (indexLayer1 > 0) {
                this.getLayer1GC().drawImage(this.mapTilset.tileImages[indexLayer1], 0, 0,
                        tileSize, tileSize, tileX, tileY, tileSize, tileSize);
            }

            // Layer 2
            if (indexLayer2 > 0) {
                this.getLayer2GC().drawImage(this.mapTilset.tileImages[indexLayer2], 0, 0,
                        tileSize, tileSize, tileX, tileY, tileSize, tileSize);
            }

        }
    }