用lapply创建函数列表

时间:2016-12-20 13:49:54

标签: r list function auto-generate

有没有办法使用lapply制作以下函数列表?下面,我制作一个名为“long”的列表。我想使用lapply(或for循环)简化代码,但似乎都不起作用。谢谢。

#This works as expected
long <- list(function(x) x <- within(x, DATE <- as.Date("2013-01-01")),
             function(x) x <- within(x, DATE <- as.Date("2014-01-01")),
             function(x) x <- within(x, DATE <- as.Date("2015-01-01")))

#This does not work
long <- lapply(2013:2015, function(i) x <- within(x, DATE <- as.Date(paste(i, "01", "01", sep = "-"))))

#This does not work
for (i in 2013:2015) long <- list(function(x) x <- within(x, DATE <- as.Date(paste(i, "01", "01", sep = "-"))))

2 个答案:

答案 0 :(得分:4)

也许最简单的方法是添加另一个function

long <- lapply(2013:2015,
              function(i) function(x) {
                           x <- within(x, DATE <- as.Date(paste(i, "01", "01", sep = "-")))})

检查元素是否为函数

typeof(long[[1]])
[1] "closure"

测试

# empty list, x
x <- list()
x <- long[[1]](x)
x
$DATE
[1] "2013-01-01"

正如@Roland在评论中提到的那样,强制评估i论证会更安全。

long <- lapply(2013:2015, function(i) {
                            force(i);
                            function(x) x <- within(x,
                                            DATE <- as.Date(paste(i, "01", "01", sep = "-")))
                           })

答案 1 :(得分:3)

有一些bquote魔法:

dates <- c("2013-01-01", "2014-01-01", "2015-01-01")

lapply(dates, function(d) eval(bquote(function(x) within(x, DATE <- as.Date(.(d))))))

#[[1]]
#function (x) 
#within(x, DATE <- as.Date("2013-01-01"))
#<environment: 0x000002b1815ba450>
#
#[[2]]
#function (x) 
#within(x, DATE <- as.Date("2014-01-01"))
#<environment: 0x000002b1815ae320>
#
#[[3]]
#function (x) 
#within(x, DATE <- as.Date("2015-01-01"))
#<environment: 0x000002b1815a1520>

(赋值x <- within(...)在函数内部是多余的。)

说明:bquote创建一个未评估的表达式对象,其中.(*)标记的符号由其值替换。 eval然后评估表达式。

在这种情况下,bquote会创建一个使用function(x) ...生成函数的调用,并插入特定日期,因此如果d的值为"2013-01-01",则bquote(function(x) ... as.Date(.(d)) 1}}会导致未评估的表达式function(x) ... as.Date("2013-01-01")。当您对此调用eval时,结果是一个包含所需函数体的函数对象。

有关详细信息,请参阅?eval?bquote