如何对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"))