如何将列entires作为参数传递给函数,然后创建一个新列,它是另外两个函数的函数?例如,使用this出色的函数将日期添加到日期,并采用此示例数据框:
df <- structure(
list(
date = structure(
c(
17135,
17105,
17105,
17074,
17286,
17317,
17317,
17347,
17105,
17317
),
class = "Date"
),
monthslater = c(10,
11, 13, 14, 3, 3, 3, 3, 4, NA)
),
.Names = c("date", "monthslater"),
row.names = c(NA, 10L),
class = "data.frame"
)
我想创建一个新列,我将列date
和monthslater
中的条目传递给函数add.months
我会认为这样的东西会起作用:
df$newdate <- add.months(df$date, df$monthslater)
但事实并非如此。
该功能的完整代码是:
add.months <- function(date,n) seq(date, by = paste(n, "months"), length = 2)[2]
答案 0 :(得分:6)
使用%m+%
中的lubridate
- 包:
library(lubridate)
df$newdate <- df$date %m+% months(df$monthslater)
给出:
> df date monthslater newdate 1 2016-11-30 10 2017-09-30 2 2016-10-31 11 2017-09-30 3 2016-10-31 13 2017-11-30 4 2016-09-30 14 2017-11-30 5 2017-04-30 3 2017-07-30 6 2017-05-31 3 2017-08-31 7 2017-05-31 3 2017-08-31 8 2017-06-30 3 2017-09-30 9 2016-10-31 4 2017-02-28 10 2017-05-31 4 2017-09-30
以类似的方式,您还可以添加日期或年份:
df$newdate2 <- df$date %m+% days(df$monthslater)
df$newdate3 <- df$date %m+% years(df$monthslater)
给出:
> df date monthslater newdate newdate2 newdate3 1 2016-11-30 10 2017-09-30 2016-12-10 2026-11-30 2 2016-10-31 11 2017-09-30 2016-11-11 2027-10-31 3 2016-10-31 13 2017-11-30 2016-11-13 2029-10-31 4 2016-09-30 14 2017-11-30 2016-10-14 2030-09-30 5 2017-04-30 3 2017-07-30 2017-05-03 2020-04-30 6 2017-05-31 3 2017-08-31 2017-06-03 2020-05-31 7 2017-05-31 3 2017-08-31 2017-06-03 2020-05-31 8 2017-06-30 3 2017-09-30 2017-07-03 2020-06-30 9 2016-10-31 4 2017-02-28 2016-11-04 2020-10-31 10 2017-05-31 4 2017-09-30 2017-06-04 2021-05-31
答案 1 :(得分:1)
或者用基础R:
df$newdate <- mapply(add.months, df[[1]], df[[2]], SIMPLIFY = FALSE)
> df
date monthslater newdate
1 2016-11-30 10 2017-09-30
2 2016-10-31 11 2017-10-01
3 2016-10-31 13 2017-12-01
4 2016-09-30 14 2017-11-30
5 2017-04-30 3 2017-07-30
6 2017-05-31 3 2017-08-31
7 2017-05-31 3 2017-08-31
8 2017-06-30 3 2017-09-30
9 2016-10-31 4 2017-03-03
10 2017-05-31 4 2017-10-01
答案 2 :(得分:1)
对于您当前的特定问题,请考虑mapply
将这两个向量元素传递到已定义的函数中。由于 monthslater 包含NA
,因此请为定义的函数添加tryCatch
。
add.months <- function(date, n) {
tryCatch(seq(date, by = paste(n, "months"), length = 2)[2],
warning = function(w) return(NA),
error = function(e) return(NA))
}
df$newdate <- as.Date(mapply(add.months, df$date, df$monthslater), origin="1970-01-01")
df
# date monthslater newdate
# 1 2016-11-30 10 2017-09-30
# 2 2016-10-31 11 2017-10-01
# 3 2016-10-31 13 2017-12-01
# 4 2016-09-30 14 2017-11-30
# 5 2017-04-30 3 2017-07-30
# 6 2017-05-31 3 2017-08-31
# 7 2017-05-31 3 2017-08-31
# 8 2017-06-30 3 2017-09-30
# 9 2016-10-31 4 2017-03-03
# 10 2017-05-31 NA <NA>
另外,请注意涉及2月底的author's item,因此#9将提前3天延长。