如何用lapply定义多个变量? [英] How to define multiple variables with lapply?
问题描述
我想将具有不同值的多个变量的函数应用于列表。我知道如何用一个变化的变量来做到这一点
sapply(c(1:10),function(x)x * 2 )
#[1] 2 4 6 8 10 12 14 16 18 20
但不是与两个。我首先手动向你展示我想要的东西(实际上我使用 lapply()
但 sapply()
):
#manual
a < - sapply(c(1:10),function(x,y = 2)x * y)
b < - sapply(c(1:10),函数(x,y = 3)x * y)
c < - sapply(c(1:10),函数(x,y = 4)x * y)
c(a,b,c)
#[1] 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12
#[24] 16 20 24 28 32 36 40
是我尝试定义 x
和 y
。
#attempt
X < - list(x = 1:10,y = 2:4)
sapply(c(1:10,2 :4),函数(x,y)x * y)
#FUN(X [[i]],...)中的错误:缺少参数y,没有默认
解决方案的基准
library(microbenchmark)
microbenchmark(sapply = as.vector(sapply(1:10,function(x,y)x * y,2:4 )),
mapply = mapply(FUN = function(x,y)x * y,1:10,rep(x = 2:4,each = 10)),
sapply2 = as.vector(sapply(1:10,函数(y)sapply(2:4,function(x)x * y))),
outer = c(outer(1:10,2:4,function(x,y)x * y)) )
#单位:微秒
#表达式最小值lq平均值中值uq最大值neval
#sapply 34.212 36.3500 62.44864 39.1295 41.9090 2304.542 100
#mapply 62.008 65.8570 87.82891 70.3470 76.5480 1283.342 100
#sapply2 196.714 203.9835 262.09990 223.6550 232.2080 3344.129 100
#outer 7.698 10.4775 13.02223 12.4020 13.4715 53.883 100
通用解决方案
尝试 outer
:
$ b $
c(outer(1:10,2:4,Vectorize(function(x,y)x * y)))
## [1] 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20
## [26] 24 28 32 36 40
如果函数已经被Vectorized
如果函数已经被矢量化了,就像它在这里一样,那么我们可以省略 Vectorize
:
c(outer(1:10,2:4,function(x ,y)x * y))
## [1] 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20
## [26 ] 24 28 32 36 40
问题中显示的具体示例
事实上,在这种特殊情况下,显示的匿名函数是默认函数,所以这是可行的:
c外(1:10,2:4))
## [1] 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20
# #[26] 24 28 32 36 40
在这种特殊情况下,我们可以使用:
c(1:10%o%2:4)
## [1] 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20
## [26] 24 28 32 36 40
如果输入是列表X
如果您的出发点是问题中显示的 X
然后:
c(outer(X [[1]],X [[2]],Vectorize(函数(x,y)x * y)))
## [1] 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20
## [26] 24 28 32 36 40
或p
$ $ p code c(do.call(outer, c(unname(X),Vectorize(函数(x,y)x * y))))
## [1] 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20
## [26] 24 28 32 36 40
其中如果适用,前面的部分适用于缩短它。
I want to apply a function with multiple variables with different values to a list. I know how to do this with one changing variable
sapply(c(1:10), function(x) x * 2)
# [1] 2 4 6 8 10 12 14 16 18 20
but not with two. I show you first manually what I want (actually I use lapply()
but sapply()
is more synoptic in SO):
# manual
a <- sapply(c(1:10), function(x, y=2) x * y)
b <- sapply(c(1:10), function(x, y=3) x * y)
c <- sapply(c(1:10), function(x, y=4) x * y)
c(a, b, c)
# [1] 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12
# [24] 16 20 24 28 32 36 40
And this is my attempt where I try to define both x
and y
.
# attempt
X <- list(x = 1:10, y = 2:4)
sapply(c(1:10, 2:4), function(x, y) x * y)
# Error in FUN(X[[i]], ...) : argument "y" is missing, with no default
Benchmark of solutions
library(microbenchmark)
microbenchmark(sapply = as.vector(sapply(1:10, function(x, y) x * y, 2:4)),
mapply = mapply( FUN = function(x, y) x * y, 1:10, rep( x = 2:4, each = 10)),
sapply2 = as.vector(sapply(1:10, function(y) sapply(2:4, function(x) x * y))),
outer = c(outer(1:10, 2:4, function(x, y) x * y)))
# Unit: microseconds
# expr min lq mean median uq max neval
# sapply 34.212 36.3500 62.44864 39.1295 41.9090 2304.542 100
# mapply 62.008 65.8570 87.82891 70.3470 76.5480 1283.342 100
# sapply2 196.714 203.9835 262.09990 223.6550 232.2080 3344.129 100
# outer 7.698 10.4775 13.02223 12.4020 13.4715 53.883 100
General solution
Try outer
:
c(outer(1:10, 2:4, Vectorize(function(x, y) x*y)))
## [1] 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20
## [26] 24 28 32 36 40
If function is Vectorized already
If the function is already vectorized, as it is here, then we can omit Vectorize
:
c(outer(1:10, 2:4, function(x, y) x * y))
## [1] 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20
## [26] 24 28 32 36 40
Particular example shown in question
In fact, in this particular case the anonymous function shown is the default so this would work:
c(outer(1:10, 2:4))
## [1] 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20
## [26] 24 28 32 36 40
Also in this particular case we could use:
c(1:10 %o% 2:4)
## [1] 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20
## [26] 24 28 32 36 40
If input is list X
If your starting point is list X
shown in the question then:
c(outer(X[[1]], X[[2]], Vectorize(function(x, y) x * y)))
## [1] 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20
## [26] 24 28 32 36 40
or
c(do.call("outer", c(unname(X), Vectorize(function(x, y) x*y))))
## [1] 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20
## [26] 24 28 32 36 40
where the prior sections apply to shorten it, if applicable.
这篇关于如何用lapply定义多个变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!