使用 purrr::invoke() 为函数提供不同的参数。
Using purrr::invoke() to supply different arguments to function.
我想 运行 R 中具有不同 k 值 (kmeans(x = iris[1:4], centers = k)
) 的 kmeans()
函数。我知道如何使用 dplyr 或 do.call()
函数执行此操作,但是我无法使用 purrr::invoke()
来执行此操作(我很确定 invoke 是执行此任务的正确函数)。我当然可以只使用 dplyr 方法(参见 this link),但令我恼火的是我无法让它与 purrr 一起工作。
在 purrr::invoke()
函数参考中,包含以下代码示例:
# Or the same function with different inputs:
invoke_map("runif", list(list(n = 5), list(n = 10)))
#> [[1]]
#> [1] 0.67176682 0.05861411 0.99706914 0.14903547 0.51855664
#>
#> [[2]]
#> [1] 0.84612005 0.71826972 0.24131402 0.54704337 0.83480182 0.02795603
#> [7] 0.46938430 0.80568003 0.81405131 0.40391100
#>
当我尝试使用 kmeans
执行此操作时,我得到以下结果
> invoke(kmeans, list(list(centers = 1), list(centers = 2)), x = iris[1:4])
Error in sample.int(m, k) : invalid 'size' argument
我也试过了
> invoke(kmeans, list(centers = 1:5), x = iris[1:4])
Error in (function (x, centers, iter.max = 10L, nstart = 1L,
algorithm = c("Hartigan-Wong", : must have same number of columns in 'x' and 'centers'
作为现实检查,我也尝试用 paste
做类似的事情
> invoke(paste, list(list(sep = "a"), list(sep = "b")), "word1", "word2")
[1] "a b word1 word2"
我期望 word1aword2
和 word1bword2
。我已经阅读了所有函数参考资料,目前我不确定如何解决这个问题。
我知道出了什么问题。首先,在这种情况下使用的正确函数是 invoke_map()
而不是 invoke()
。使用该函数时(在函数参考-.-中也有说明),可通过以下代码解决问题:
invoke_map(kmeans, list(list(centers = 1), list(centers = 2)), x = iris[1:4])
然而,如果你想要多个中心,那么写起来可能会非常乏味,所以我想出了以下我非常满意的解决方案。希望这可以帮助别人!
invoke_map(kmeans, transpose(list(centers = 1:10)), x = iris[1:4])
你为什么"quite sure that invoke is the right function for this task"?
一个简单的 map
可以:
set.seed(123) ; res1 <- invoke_map(kmeans, transpose(list(centers = 1:10)), x = iris[1:4])
set.seed(123) ; res2 <- map(1:10, kmeans, x = iris[1:4])
identical(res1, res2)
# [1] TRUE
我想 运行 R 中具有不同 k 值 (kmeans(x = iris[1:4], centers = k)
) 的 kmeans()
函数。我知道如何使用 dplyr 或 do.call()
函数执行此操作,但是我无法使用 purrr::invoke()
来执行此操作(我很确定 invoke 是执行此任务的正确函数)。我当然可以只使用 dplyr 方法(参见 this link),但令我恼火的是我无法让它与 purrr 一起工作。
在 purrr::invoke()
函数参考中,包含以下代码示例:
# Or the same function with different inputs:
invoke_map("runif", list(list(n = 5), list(n = 10)))
#> [[1]]
#> [1] 0.67176682 0.05861411 0.99706914 0.14903547 0.51855664
#>
#> [[2]]
#> [1] 0.84612005 0.71826972 0.24131402 0.54704337 0.83480182 0.02795603
#> [7] 0.46938430 0.80568003 0.81405131 0.40391100
#>
当我尝试使用 kmeans
执行此操作时,我得到以下结果
> invoke(kmeans, list(list(centers = 1), list(centers = 2)), x = iris[1:4])
Error in sample.int(m, k) : invalid 'size' argument
我也试过了
> invoke(kmeans, list(centers = 1:5), x = iris[1:4])
Error in (function (x, centers, iter.max = 10L, nstart = 1L,
algorithm = c("Hartigan-Wong", : must have same number of columns in 'x' and 'centers'
作为现实检查,我也尝试用 paste
> invoke(paste, list(list(sep = "a"), list(sep = "b")), "word1", "word2")
[1] "a b word1 word2"
我期望 word1aword2
和 word1bword2
。我已经阅读了所有函数参考资料,目前我不确定如何解决这个问题。
我知道出了什么问题。首先,在这种情况下使用的正确函数是 invoke_map()
而不是 invoke()
。使用该函数时(在函数参考-.-中也有说明),可通过以下代码解决问题:
invoke_map(kmeans, list(list(centers = 1), list(centers = 2)), x = iris[1:4])
然而,如果你想要多个中心,那么写起来可能会非常乏味,所以我想出了以下我非常满意的解决方案。希望这可以帮助别人!
invoke_map(kmeans, transpose(list(centers = 1:10)), x = iris[1:4])
你为什么"quite sure that invoke is the right function for this task"?
一个简单的 map
可以:
set.seed(123) ; res1 <- invoke_map(kmeans, transpose(list(centers = 1:10)), x = iris[1:4])
set.seed(123) ; res2 <- map(1:10, kmeans, x = iris[1:4])
identical(res1, res2)
# [1] TRUE