R:在apply函数中使用as.POSIXct()的最佳方法

R:在apply函数中使用as.POSIXct()的最佳方法,r,date,apply,posixct,R,Date,Apply,Posixct,我正在尝试设置一个新变量,该变量包含已知日期和给定年份结束之间的差异(天数)。虚拟数据如下: > Date.event <- as.POSIXct(c("12/2/2000","8/2/2001"), format = "%d/%m/%Y", tz = "Europe/London") > Year = c(2000,2001) > Dates.test <- data.frame(Date.event,Year) > Dates.test Date.ev

我正在尝试设置一个新变量,该变量包含已知日期和给定年份结束之间的差异(天数)。虚拟数据如下:

> Date.event <- as.POSIXct(c("12/2/2000","8/2/2001"), format = "%d/%m/%Y", tz = "Europe/London")
> Year = c(2000,2001)
> Dates.test <- data.frame(Date.event,Year)
> Dates.test
  Date.event Year
1 2000-02-12 2000
2 2001-02-08 2001
>Date.event Year=c(20002001)
>日期。测试日期。测试
日期.事件年份
1 2000-02-12 2000
2 2001-02-08 2001
我尝试应用一个函数来实现这一点,但它返回了一个错误

> Time.dif.fun <- function(x) {
+ as.numeric(as.POSIXct(sprintf('31/12/%s', s= x['Year']),format = "%d/%m/%Y", tz = "Europe/London") - x['Date.event'])
+ }
> Dates.test$Time.dif <- apply(
+ Dates.test, 1, Time.dif.fun
+ )

 Error in unclass(e1) - e2 : non-numeric argument to binary operator 

>Time.dif.fun日期。测试$Time.dif您可以使用
difftime
功能:

Dates.test$diff_days <- difftime(as.POSIXct(paste0(Dates.test[,2],"-12-31"),format = "%Y-%m-%d", tz = "Europe/London"),Dates.test[,1],unit="days")

Dates.test$diff_days您可以使用
ISOdate
构建年终日期,使用
difftime(…units='days')
获取年终日期

?difftime

在“difftime”对象上提供有限的算法:它们可以是 加或减,乘以或除以数值向量

如果您想做的不仅仅是有限的算术运算,只需强制使用
as.numeric()
,但您必须坚持使用您指定的任何单位

按照惯例,您可能希望使用明年年初(除夕午夜)作为当年的终点。例如:

Dates.test <- data.frame(
  Date.event = as.POSIXct(c("12/2/2000","8/2/2001"), 
                          format = "%d/%m/%Y", tz = "Europe/London")
)
# use data.table::year() to get the year of a date
year <- function(x) as.POSIXlt(x)$year + 1900L
Dates.test$Date.end <- ISOdate(year(Dates.test$Date.event)+1,1,1)

# if you don't want class 'difftime', wrap it in as.numeric(), as in:
Dates.test$Date.diff <- as.numeric(
                             difftime(Dates.test$Date.end, 
                                      Dates.test$Date.event, 
                                      units='days')
                        )
Dates.test
#   Date.event            Date.end Date.diff
# 1 2000-02-12 2001-01-01 12:00:00     324.5
# 2 2001-02-08 2002-01-01 12:00:00     327.5

Dates.test以下是一些备选方案:

1)您的代码可以处理这些更改。我们计算了s,不是因为它是必要的,而是因为下面的一行由于其长度而变得非常难以阅读。请注意,如果
x
是一个数据帧,那么
x[“年”]
也是一个数据帧,但是
x[“年”]
x$Year
一样是一个向量。由于操作都是矢量化的,因此我们不需要
apply


虽然我们还没有做这个更改,但是将s定义为
s相关问题会更容易一些:一些有用的提示,谢谢。year()是额外包的函数吗?我没有认出它。矢量化解决方案的问题在于,实际函数有多个潜在的已知日期,有时需要返回到上一年以查找其他日期,因此我想执行几个ifelse()函数。如上所述的“日期差异”也不是输出的终点,我需要将天数转换为数字,以便按额外系数进行缩放。哎呀,
年实际上是在
数据表中。表
,但您可以将其定义为上面编辑的数据包,而不是加载该数据包。@用户请参见编辑
ifelse()
已矢量化,因此我不确定您的意思。此解决方案适用于您提供的示例。请确保您的示例能够代表您要问的问题。非常方便,谢谢,尤其是在函数中定义临时“s”的顶级解决方案现在很明显,但我从未想到过。我猜这就是学习编码的全部内容!关于这一点,见第(1)条增补的评注。
Time.dif.fun <- function(x) {
  s <- sprintf('31/12/%s', x[['Year']])
  as.numeric(as.POSIXct(s, format = "%d/%m/%Y", tz = "Europe/London") -x[['Date.event']])
}
Time.dif.fun(Dates.test)
## [1] 323 326
lt <- as.POSIXlt(Dates.test$Date.event)
lt$year <- Dates.test$Year - 1900
lt$mon <- 11
lt$mday <- 31
as.numeric(lt - Dates.test$Date.event)
## [1] 323 326
with(Dates.test, as.numeric(as.Date(paste0(Year, "-12-31")) - as.Date(Date.event)))
## [1] 323 326