如何用lapply定义多个变量? [英] How to define multiple variables with lapply?

查看:164
本文介绍了如何用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆