【问题标题】:lapply using iterator as parameter for functionlapply 使用迭代器作为函数的参数
【发布时间】:2018-05-15 11:24:03
【问题描述】:

我尝试用 lapply 解决一个问题。作为一名 SAS 程序员,这种思维方式对我来说是全新的。

library(data.table)
library(lubridate)

我有一个这样的data.table

DT <- data.table(idnum= c(1001,1001,1001,1002,1002,1003,1003,1003,1003),
             a_beg= c(16079, 16700, 17000, 16074, 17000, 16074, 17000, 18081, 19000),
             a_end= c(16500, 16850, 22000, 16900, 22000, 16950, 18000, 18950, 21000))

a_beg 和 a_end 包含 sas 日期编号(自 1960-01-01 以来的天数)

这是我的功能年。我想将我的函数应用于 data.table 对象,只保留间隔与学习年重叠的行

 years <- function(DT, year) {

 DT <- DT[lubridate::date('1960-01-01')+a_beg <= lubridate::ymd(paste(year, 1, 1, sep = "-"))
        & lubridate::date('1960-01-01')+a_end >= lubridate::ymd(paste(year, 12, 31, sep = "-")), ]
 DT
 }

不使用 apply 就可以了...

year2005 <- years(DT, 2005)

我想做这样的事情... 跨过学年 使用 bind_rows 和管道进入 data.table

 DT <- bind_rows(lapply(DT, 2004:2015, years())) %>% data.table()

我想用迭代器作为函数的参数,不知道怎么做。

【问题讨论】:

  • 一遍又一遍地将所有列转换为日期有什么意义?已经将a_bega_end 设置为日期格式没有意义吗?另外你为什么要迭代?您需要计算每个间隔中有多少日期?如果是这样,我建议使用结合by = .EACHI 的连接。最后,你在这里混合了太多的包。这里根本不需要 lubrdate。并且 data.table 有 rbindlist 所以在 dplyr 中也不需要。
  • 阅读初学者的语法一定很烦人,所以还是感谢您仔细研究一下。仍在学习 R 并努力摆脱 SAS-Thinking ;-)
  • 其实没那么烦人。我只是想了解您要达到的最终结果是什么。

标签: r parameters iterator data.table lapply


【解决方案1】:

我想你想要的是

years <- function(year, DTbl) {
    #data.table changes by reference so you do not want your subset to overwrite the original DT
    DTbl[lubridate::date('1960-01-01')+a_beg <= lubridate::ymd(paste(year, 1, 1, sep = "-"))
            & lubridate::date('1960-01-01')+a_end >= lubridate::ymd(paste(year, 12, 31, sep = "-")), ]    
}
bind_rows(lapply(2004:2015, years, DTbl=DT)) %>% data.table()

或者如果我们使用更多的语法,你可以做一个的非等连接,如下所示:

DT[, ':=' (
    a_beg = as.Date(a_beg, origin="1960-01-01"),
    a_end = as.Date(a_end, origin="1960-01-01")
)]

yearRanges <- data.table(beg=seq(as.Date("2004-01-01"), by="1 year", length.out=12), 
    end=seq(as.Date("2004-12-31"), by="1 year", length.out=12))

DT[yearRanges,
    .(YEAR=year(beg), idnum=x.idnum, a_beg=x.a_beg, a_end=x.a_end),
    on=.(a_beg <= beg, a_end >= end),
    allow.cartesian=TRUE]

【讨论】:

  • 非常感谢,这非常有效。一些 data.table 语法对我来说是新的,我今天将仔细研究一下,看看它在 8GB 数据集上更快;-)
猜你喜欢
  • 2020-05-08
  • 1970-01-01
  • 2013-12-13
  • 2020-03-09
  • 2021-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-31
相关资源
最近更新 更多