如何对R中的日期分量进行算术运算

如何对R中的日期分量进行算术运算,r,date,R,Date,我试图计算一个由日期组成的函数(年、月、日)。我将数据读入数据帧,将字符串解析为日期,然后,我希望,对日期的组成部分进行一些算术运算 这是我的数据文件: timestamp,value "2014-01-23 12:30:00",123 "2015-11-30 15:45:00",456 "2016-07-29 09:15:00",789 这是我的R课程:(我正在Ubuntu 14.04上使用R3.0.2) >x 时间戳值 1 2014-01-23 12:30:00 123 2 2015-

我试图计算一个由日期组成的函数(年、月、日)。我将数据读入数据帧,将字符串解析为日期,然后,我希望,对日期的组成部分进行一些算术运算

这是我的数据文件:

timestamp,value
"2014-01-23 12:30:00",123
"2015-11-30 15:45:00",456
"2016-07-29 09:15:00",789
这是我的R课程:(我正在Ubuntu 14.04上使用R3.0.2)

>x
时间戳值
1 2014-01-23 12:30:00   123
2 2015-11-30 15:45:00   456
3 2016-07-29 09:15:00   789
>x1-x1
[1] "2014-01-23 12:30:00" "2015-11-30 15:45:00" "2016-07-29 09:15:00"
>x1.t x1.t
[1] "2014-01-23 12:30:00" "2015-11-30 15:45:00" "2016-07-29 09:15:00"

>x1.t.combo您遇到的问题是POSIXlt本身是一个具有多个元素的类型,因此*apply命令将函数应用于它的每个元素。您可以通过
unlist(x1.t)
查看元素

所以你必须“绕开”它。有一种简单的方法,您不必首先转换它:

> x <- c("2014-01-23 12:30:00", "2015-11-30 15:45:00")
> x
[1] "2014-01-23 12:30:00" "2015-11-30 15:45:00"
> y <- sapply (x, function (t) { t <- as.POSIXlt(t); (t$year - 114)*12 + (t$mon + 1) })
> y
2014-01-23 12:30:00 2015-11-30 15:45:00 
                  1                  23 
>x
[1] "2014-01-23 12:30:00" "2015-11-30 15:45:00"
>y×x
[1] “2014-01-23 12:30:00 EET”“2015-11-30 15:45:00 EET”

>ysapply
lapply
都会产生相同的错误,因为
x1.t
是一个列表,它们逐个传递列表中的元素。第一个是3元素(原子的,不是递归的)秒向量

> x1.t[[1]]   # same as x1.t[['sec']]
[1] 0 0 0
..此外,它(以及所有其他组件)正在以没有名称的方式传递。因此,即使是第5个或第6个列表中的year元素,在到达匿名函数体时也不会有“year”的名称

dput(x1.t)
structure(list(sec = c(0, 0, 0), min = c(30L, 45L, 15L), hour = c(12L, 
15L, 9L), mday = c(23L, 30L, 29L), mon = c(0L, 10L, 6L), year = 114:116, 
    wday = c(4L, 1L, 5L), yday = c(22L, 333L, 210L), isdst = c(0L, 
    0L, 1L), zone = c("PST", "PST", "PDT"), gmtoff = c(NA_integer_, 
    NA_integer_, NA_integer_)), .Names = c("sec", "min", "hour", 
"mday", "mon", "year", "wday", "yday", "isdst", "zone", "gmtoff"
), class = c("POSIXlt", "POSIXt"))

这类似于人们认为data.frame中的第一个元素是第一行或data.frame的长度是案例数(实际上是列数)时所犯的错误。

首先,
sapply
似乎是这里使用的错误。其次,我看不出
x1.t[1]$year
是如何工作的。尝试加载
library(lubridate)
并使用
year(x1.t)
作为示例。所以
x1.t.combo感谢您的回复。(1) 如果你想推荐一个函数而不是
sapply
,我会试试看。(2) 嗯,
x1.t[1]$year
很管用——正如人们所说,你不能与成功争辩。。。(3) 谢谢你指出lubridate——我一定会试试看。@Hugh谢谢你建议lubridate。当我尝试
year(x1.t[[3]])
时,我得到:
as.POSIXlt.numeric(x,tz=tz(x))中的错误:必须提供“origin”
。但是,
origin
似乎不是
year
的参数。如何解决该错误?当字符串被解析为日期时,可能需要提供
origin
?但就目前情况而言,解析在没有
origin
的情况下成功了。天哪,我现在比刚开始时更困惑了。。。(1) “POSIXlt本身是一个具有多个元素的类型,因此*apply命令将函数应用于它的每个元素”--如果
sapply
的第一个参数是POSIXlt项的列表,为什么传递给函数的每个项都不是POSIXlt的实例?(2)
t的功能是什么?是的,嗯,有点让人困惑。1) 我不知道,我对它不太熟悉。2) 该代码的作用是复制粘贴。如您所见,我的代码的第一个块在函数之外不进行转换。3) 然后忽略第二个街区,只使用第一个街区。例如,如果您想找出日期差异,您可能需要进行转换。“x1.t是一个列表,它们正在逐个传递列表中的元素”——这似乎很奇怪;我希望映射函数将
x1.t
的每个元素作为一个聚合传递。为什么函数接收的参数
t
不是POSIXlt的实例?我在外推其他语言中映射函数的行为,看起来R中的映射函数的行为方式有很大的不同。没关系,不过有点意外。谢谢你的信息性评论。我同意你的行为并不像人们所期望的那样。POSIXlt结构是一个非常奇怪的结构。使用POSIXct几乎总是会更好,它更可能以人们期望的方式运行(以你如何思考它如何处理时区为模式,这会让我继续感到困惑。)好吧,我对Sappy比对POSIXlt更困惑——我希望映射函数将第一个参数的元素传递给函数,但看起来它实际上传递了部分元素。对吗?如果不是,那么看Sappy在做什么的正确方法是什么?Sappy和lapply都在传递POSIXlt对象中的单个列表。它构建为一组列表。这就好像您正在处理一个数据帧,并试图使用它来传递单个行。你也会经历类似的困惑。好吧,我现在明白了,sapply和lapply正在传递所有的年份、月份、日期等,而不是第一个元素的所有字段,第二个元素的所有字段,等等。;如果将字段写为列,将元素写为行,那么sapply和lapply将映射到列而不是行,这让我感到惊讶。是否有映射函数可以按元素而不是字段进行映射<代码>应用(如.matrix(x1.t),1,函数(t){…})
似乎很接近,但函数中的
t$year
t$mon
失败,并显示“$运算符对原子向量无效”。
> x1.t[[1]]   # same as x1.t[['sec']]
[1] 0 0 0
dput(x1.t)
structure(list(sec = c(0, 0, 0), min = c(30L, 45L, 15L), hour = c(12L, 
15L, 9L), mday = c(23L, 30L, 29L), mon = c(0L, 10L, 6L), year = 114:116, 
    wday = c(4L, 1L, 5L), yday = c(22L, 333L, 210L), isdst = c(0L, 
    0L, 1L), zone = c("PST", "PST", "PDT"), gmtoff = c(NA_integer_, 
    NA_integer_, NA_integer_)), .Names = c("sec", "min", "hour", 
"mday", "mon", "year", "wday", "yday", "isdst", "zone", "gmtoff"
), class = c("POSIXlt", "POSIXt"))