Lubridate:如何减去一个月的最后一次观察

时间:2016-08-22 16:31:39

标签: r time-series lubridate

我有一个时间序列,并想获得每个月最后一次观察的信息。这个问题不是关于生成新的时间序列,而是查找现有时间序列中每个月的最后一次观察。最后一次观察可能不是一个月的最后一天。以下只是一个小例子,

date <- c(ymd(20010129, 20010228, 20010330, 20010429), ymd(20010501) + days(1:90))

# "2001-01-29" "2001-02-28" "2001-03-30" "2001-04-29" "2001-05-02" "2001-05-03" "2001-05-04" "2001-05-05"
# "2001-05-06" "2001-05-07" "2001-05-08" "2001-05-09" "2001-05-10" "2001-05-11" "2001-05-12" "2001-05-13"
# "2001-05-14" "2001-05-15" "2001-05-16" "2001-05-17" "2001-05-18" "2001-05-19" "2001-05-20" "2001-05-21"
# "2001-05-22" "2001-05-23" "2001-05-24" "2001-05-25" "2001-05-26" "2001-05-27" "2001-05-28" "2001-05-29"
# "2001-05-30" "2001-05-31" "2001-06-01" "2001-06-02" "2001-06-03" "2001-06-04" "2001-06-05" "2001-06-06"
# "2001-06-07" "2001-06-08" "2001-06-09" "2001-06-10" "2001-06-11" "2001-06-12" "2001-06-13" "2001-06-14"
# "2001-06-15" "2001-06-16" "2001-06-17" "2001-06-18" "2001-06-19" "2001-06-20" "2001-06-21" "2001-06-22"
# "2001-06-23" "2001-06-24" "2001-06-25" "2001-06-26" "2001-06-27" "2001-06-28" "2001-06-29" "2001-06-30"
# "2001-07-01" "2001-07-02" "2001-07-03" "2001-07-04" "2001-07-05" "2001-07-06" "2001-07-07" "2001-07-08"
# "2001-07-09" "2001-07-10" "2001-07-11" "2001-07-12" "2001-07-13" "2001-07-14" "2001-07-15" "2001-07-16"
# "2001-07-17" "2001-07-18" "2001-07-19" "2001-07-20" "2001-07-21" "2001-07-22" "2001-07-23" "2001-07-24"
# "2001-07-25" "2001-07-26" "2001-07-27" "2001-07-28" "2001-07-29" "2001-07-30"

我想继续观察"2001-01-29""2001-02-28""2001-03-30""2001-04-29""2001-05-31""2001-06-30"和{{1 }}。有没有办法实现它?

3 个答案:

答案 0 :(得分:3)

您可以按月对日期进行分组并计算最大值:

library(lubridate)
unique(ave(date, month(date), FUN = max))

# [1] "2001-01-29" "2001-02-28" "2001-03-30" "2001-04-29"
# [5] "2001-05-31" "2001-06-30" "2001-07-30"

答案 1 :(得分:1)

我们可以使用data.table。转换&#39;日期&#39;向量data.table的向量,按照yearmonth的日期&#39;分组我们得到了max&#39; date&#39;。

library(data.table)
as.data.table(date)[, .(Date = max(date)), .(Year = year(date), Month = month(date))]
#   Year Month       Date
#1: 2001     1 2001-01-29
#2: 2001     2 2001-02-28
#3: 2001     3 2001-03-30
#4: 2001     4 2001-04-29
#5: 2001     5 2001-05-31
#6: 2001     6 2001-06-30
#7: 2001     7 2001-07-30

或者使用基于base R的简单tapply方法,而不是使用与原始向量相同长度的向量,然后使用unique

do.call("c", tapply(date, list(month(date), year(date)), 
                FUN = function(x) list(max(x))))
#[1] "2001-01-29" "2001-02-28" "2001-03-30" "2001-04-29" "2001-05-31" 
#[6] "2001-06-30" "2001-07-30"

或以简洁的方式

 unname(as.Date(tapply(date, substr(date, 1,7), FUN = max), origin = "1970-01-01"))
 #[1] "2001-01-29" "2001-02-28" "2001-03-30" "2001-04-29" "2001-05-31" 
 #[6] "2001-06-30" "2001-07-30"

此外,我们可以通过检查相邻元素(假设它是有序的)来获得没有任何分组的输出,并且它应该非常有效。

v1 <- substr(date, 1, 7)
date[c(v1[-1]!= v1[-length(v1)], TRUE)]
[1] "2001-01-29" "2001-02-28" "2001-03-30" "2001-04-29" "2001-05-31" 
[6] "2001-06-30" "2001-07-30"

基准

date1 <- c(ymd(20010129, 20010228, 20010330, 20010429), ymd(20010501) + days(1:1e6))
system.time(as.data.table(date1)[, .(Date = max(date1)), 
      .(Year = year(date1), Month = month(date1))])
#   user  system elapsed 
#   5.53    0.05    5.58  


system.time({
 v1 <- substr(date1, 1, 7)
 date1[c(v1[-1]!= v1[-length(v1)], TRUE)]
})
# user  system elapsed 
#  10.25    0.23   10.49 

基于上述表现,data.table方法非常有效,尽管相邻元素之间的base R比较也并非落后,而闪烁的所有内容都不是黄金。

system.time(unique(ave(date1, year(date1), month(date1), FUN = max)))
#   user  system elapsed 
# 242.35  120.80  364.55 

答案 2 :(得分:0)

public static SpannableStringBuilder makeSectionOfTextBold(String text, String... textToBold) { SpannableStringBuilder builder = new SpannableStringBuilder(text); for (String textItem : textToBold) { if (textItem.length() > 0 && !textItem.trim().equals("")) { //for counting start/end indexes String testText = text.toLowerCase(Locale.US); String testTextToBold = textItem.toLowerCase(Locale.US); int startingIndex = testText.indexOf(testTextToBold); int endingIndex = startingIndex + testTextToBold.length(); if (startingIndex >= 0 && endingIndex >= 0) { builder.setSpan(new StyleSpan(Typeface.BOLD), startingIndex, endingIndex, 0); } } } return builder; } 来自endpoints包的函数正如其名称所暗示的那样:

xts

参数的有效值包括:“us”(微秒),“微秒”,“ms”(毫秒),“毫秒”,“秒”(秒),“秒”,“分钟”(分钟) ,“分钟”,“小时”,“天”,“周”,“月”,“宿舍”和“年”。<​​/ p>