使用 lapply 创建函数列表
Make list of functions with lapply
有什么方法可以使用 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 = "-"))))
也许最简单的方法是添加另一个 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 = "-")))
})
有一些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))
导致 未计算 表达式 function(x) ... as.Date("2013-01-01")
。当你对此调用 eval
时,结果是一个包含你想要的函数体的函数对象。
有关详细信息,请参阅 ?eval
和 ?bquote
。
有什么方法可以使用 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 = "-"))))
也许最简单的方法是添加另一个 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 = "-")))
})
有一些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))
导致 未计算 表达式 function(x) ... as.Date("2013-01-01")
。当你对此调用 eval
时,结果是一个包含你想要的函数体的函数对象。
有关详细信息,请参阅 ?eval
和 ?bquote
。