如何在lapply()、compose()和partial()中索引函数输出取最后元素
问题
我用lapply()处理包含2个文件的列表,通过compose()组合多个函数:先从文件加载数据(返回一个包含2个日期列表的列表),再提取每个列表的最后元素。
但用tail()时没得到单个日期,反而返回了整个列表。我发现通过data[[1]]和data[[2]]索引加载后的数据能拿到正确的最后元素,但不知道怎么在lapply()、compose()和partial()的组合里实现这个逻辑。
原代码
dates <- list( from = lapply(file_last_dates, purrr::compose(as.Date, purrr::partial(sum,1))), up_to = lapply(tamsat_retrieved_dates, purrr::compose(purrr::partial(tail,n=1), st_load_rds)) )
原输出结构
List of 2 $ from :List of 1 ..$ file_last_dates.rds: Date[1:1], format: "2023-01-01" $ up_to:List of 2 ..$ :List of 1 .. ..$ ST/rfe/raw/ssa/tamsat-v3.1/dekadal/retrieved_dates.rds: Date[1:1419], format: "1984-01-10" "1984-01-20" "1984-01-31" "1984-02-10" ... ..$ :List of 1 .. ..$ ST/rfe/raw/ssa/tamsat-v3.1/daily/retrieved_dates.rds: Date[1:14396], format: "1984-01-01" "1984-01-02" "1984-01-03" "1984-01-04" ...
预期效果验证
直接索引后用tail()能得到想要的单个日期:
tail(st_load_rds(tamsat_retrieved_dates)[[1]],n=1)
tail(st_load_rds(tamsat_retrieved_dates)[[2]],n=1)
输出:
"2023-05-31"
相关数据结构
st_load_rds(tamsat_retrieved_dates)的结构:
List of 2 $ ST/rfe/raw/ssa/tamsat-v3.1/dekadal/retrieved_dates.rds: Date[1:1419], format: "1984-01-10" "1984-01-20" "1984-01-31" "1984-02-10" ... $ ST/rfe/raw/ssa/tamsat-v3.1/daily/retrieved_dates.rds : Date[1:14396], format: "1984-01-01" "1984-01-02" "1984-01-03" "1984-01-04" ...
file_last_dates的结构:
List of 1 $ file_last_dates.rds: Date[1:1], format: "2022-12-31"
解决方案
问题核心是st_load_rds返回的是带命名的单元素列表(每个文件对应一个命名列表项,内部是日期向量),直接用tail()会作用在整个列表上,而非列表内的日期向量。需要先提取向量,再取最后一项。
修改后的代码(匿名函数版)
library(purrr) dates <- list( from = lapply(file_last_dates, compose(as.Date, partial(sum, 1))), up_to = lapply(tamsat_retrieved_dates, compose(partial(tail, n = 1), function(x) x[[1]], st_load_rds)) )
简化写法(pluck函数版)
用purrr::pluck()替代匿名函数,更贴合purrr风格:
dates <- list( from = lapply(file_last_dates, compose(as.Date, partial(sum, 1))), up_to = lapply(tamsat_retrieved_dates, compose(partial(tail, n = 1), pluck(1), st_load_rds)) )
逻辑说明
compose()的执行顺序是从右到左:
- 先执行
st_load_rds加载文件,得到带命名的单元素列表 - 再用
pluck(1)或x[[1]]提取列表内的日期向量 - 最后用
tail(n=1)取向量的最后一个元素
这样就能得到每个文件对应的单个日期,而非整个列表。
内容的提问来源于stack exchange,提问作者Billy Ray
相关产品推荐
相关产品推荐

