有没有办法使用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 = "-"))))
答案 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
。