R 如何在每个月的最后一天对数据帧进行子集划分

R 如何在每个月的最后一天对数据帧进行子集划分,r,xts,zoo,R,Xts,Zoo,我有一个df: dates V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 1999-05-31 66 65 64 63 62 61 60 59 58 57 1999-06-01 67 66 65 64 63 62 61 60 59 58 1999-06-02 68 67 66 65 64 63 62 61 60 59 1999-06-03 69 68 67 66 65 64 6

我有一个df:

     dates  V1  V2  V3  V4  V5  V6  V7  V8  V9  V10
1999-05-31  66  65  64  63  62  61  60  59  58  57
1999-06-01  67  66  65  64  63  62  61  60  59  58
1999-06-02  68  67  66  65  64  63  62  61  60  59
1999-06-03  69  68  67  66  65  64  63  62  61  60
1999-06-04  70  69  68  67  66  65  64  63  62  61
1999-06-17  79  78  77  76  75  74  73  72  71  70
1999-06-18  80  79  78  77  76  75  74  73  72  71
1999-06-21  81  80  79  78  77  76  75  74  73  72
1999-06-22  82  81  80  79  78  77  76  75  74  73
1999-06-23  83  82  81  80  79  78  77  76  75  74
1999-06-24  84  83  82  81  80  79  78  77  76  75
1999-06-25  85  84  83  82  81  80  79  78  77  76
1999-06-28  86  85  84  83  82  81  80  79  78  77
1999-06-29  87  86  85  84  83  82  81  80  79  78
1999-06-30  88  87  86  85  84  83  82  81  80  79
我想在每个月的最后一天将上述df子集。也就是说,只有1999-05-31和1999-06-30这两个日期才会出现。实际的数据帧要大得多,最后的日期可能是每个月的28日、29日等等。 因此,我希望输出类似于:

dates   V1  V2  V3  V4  V5  V6  V7  V8  V9  V10
1999-05-31  66  65  64  63  62  61  60  59  58  57 
1999-06-30  88  87  86  85  84  83  82  81  80  79
1999-10-29  175 174 173 172 171 170 169 168 167 166

我试图在zoo或其他软件包中找到一些功能,但找不到。。。非常感谢所有的建议

这将选择该月的最后几天:

df[as.numeric(substr(as.Date(df$dates) + 1, 9, 10))
   < as.numeric(substr(df$dates, 9, 10)), ]

#        dates V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
#1  1999-05-31 66 65 64 63 62 61 60 59 58  57
#15 1999-06-30 88 87 86 85 84 83 82 81 80  79
df[as.numeric(substr(as.Date(df$dates)+1,9,10))
请注意,此解决方案取决于每天的绝对月数(与您的数据无关)

如果要在实际数据中选择每个月的最后一天,请使用以下命令:

df[c(diff(as.numeric(substr(df$dates, 9, 10))) < 0, TRUE), ]
df[c(diff(as.numeric)(substr(df$dates,9,10))<0,TRUE),]

假设日期格式正确,且源数据框为
x

> library(xts)
> x[endpoints(x$dates, on = "months"), ]
        dates V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1  1999-05-31 66 65 64 63 62 61 60 59 58  57
15 1999-06-30 88 87 86 85 84 83 82 81 80  79

这里有一个使用dplyr的选项:

library(dplyr)

df %>% 
  mutate(dates = as.Date(dates)) %>% 
  mutate(yr_mnth = format(dates, '%Y-%m')) %>% 
  group_by(yr_mnth) %>% 
  filter(dates == max(dates))

# or if you wanted the first observation of each month:
df %>% 
  mutate(dates = as.Date(dates)) %>% 
  mutate(yr_mnth = format(dates, '%Y-%m')) %>% 
  group_by(yr_mnth) %>% 
  filter(dates == min(dates))

再次感谢你,斯文!你有很好的技巧!好啊谢谢!:)但是为什么包含
TRUE
?如果排除它,我似乎会得到相同的答案…命令
diff(as.numeric(substr(df$dates,9,10))<0
返回长度
nrow(df)-1
的逻辑向量,因此我将此向量与另一个
TRUE
组合使用它来选择
df
行的子集。向量的长度和逻辑索引向量的长度应该相同。如果逻辑索引短一个元素,那么逻辑向量的第一个值也将用作它的最后一个值。如果我想查找每个月的第一天而不是每个月的最后一天,我是否正确地认为我可以将df[c(diff(as.numeric(subsr(df$dates,9,10))<0,TRUE),]更改为df[c(diff((as.numeric(subsr(df$dates,9,10)))+1>0,为真),]?:)@用户1665355不,只需更改
TRUE
df[c(TRUE,diff(as.numeric(substr(df$dates,9,10)))<0),]
谢谢!我怎样才能找到每个月的第一次观察结果?我可以简单地执行x[endpoints(x$dates,on=“months”)+1]吗,或者是否有一些特定的功能?顺致敬意,