来自不同来源的年度数据在同一年有不同的日期

Annual data from different sources has different dates for the same year

我合并了从不同来源下载的数据。数据是年度数据(每年一次观察),但日期不一致 "anchored",例如我有“1992-12-31”或“1993-01-01”。处理此类数据的推荐方法是什么? 如何根据日期中 'closeness' 的标准合并 data.frame 中的某些行?

关于在数据框中合并行的现有问题和答案,可以通过一些调整适用于我的情况,但这里我的问题是特定于日期和处理“1992-12-”共存的问题31”和“1992-01-01”的年度数据---我的数据来自OECD、IMF、World Bank等机构。也许一个聪明的包已经知道这些机构的标准约定?

我对代码的效率和可读性都很感兴趣。我也非常愿意接受 data.table 解决方案。相关 question/answer 与日期无关:how do I replace numeric codes with value labels from a lookup table?

输入:

    df <- structure(list(year = c("1992-12-31", "1993-01-01", "1993-12-31", "1994-01-01"), x = c(NA, 1, NA, 4), y = c(2, NA, 3, NA)), .Names = c("year", "x", "y"), row.names = c(NA, -4L), class = "data.frame")
    df
    ##        year  x  y
    ##1 1992-12-31 NA  2
    ##2 1993-01-01  1 NA
    ##3 1993-12-31 NA  3
    ##4 1994-01-01  4 NA

期望输出:

    df2
    ##        year x y
    ##1 1993-01-01 1 2
    ##2 1994-01-01 4 3

(假设这样的映射“1992-12-31”=“1993-01-01”)

解决方法:

    key <- c("1992-12-31" = "1993-01-01", 
             "1993-12-31" = "1994-01-01")
    matched <- match(df$year, names(key))
    df$year <- ifelse(is.na(matched),
                      df$year, key[matched])
    df
    ##        year  x  y
    ##1 1993-01-01 NA  2
    ##2 1993-01-01  1 NA
    ##3 1994-01-01 NA  3
    ##4 1994-01-01  4 NA
    df <- aggregate(x = df[c("x","y")], 
        by = list(year = df$year), mean, na.rm = TRUE)
    df
    ##        year x y
    ##1 1993-01-01 1 2
    ##2 1994-01-01 4 3

但我很想知道是否有更聪明的方法。

旁注:我确实意识到我现有的数据集已经适合绘图,例如与 base Rggplot2(Hadley Wickham):

plot(df1$x, df1$y)
library(ggplot2)
ggplot(df1, aes(x = year)) + geom_point(aes(y = x)) + geom_point(aes(y = y))

也许所有日期都加一天,然后将日期四舍五入到 YYYYMM,然后汇总。

library(lubridate)
library(dplyr)

#add one day then group
df %>% 
  mutate(year = ymd(year),
         YYYYMM = format(year + 1, "%Y%m")) %>% 
  group_by(YYYYMM) %>% 
  summarise(x = sum(x, na.rm = TRUE),
            y = sum(y, na.rm = TRUE))

#output
#   YYYYMM     x     y
#    (chr) (dbl) (dbl)
# 1 199301     1     2
# 2 199401     4     3

使用库 dplyr 的一个解决方案是将 id 分配给属于同一组的日期组,然后根据这些组进行汇总:

library(dplyr)
df %>%
  arrange(year) %>%
  mutate(id = cumsum(as.numeric(difftime(lead(df$year, default = max(year)), df$year, units = 'days')) == 1)) %>%
  group_by(id) %>%
  summarise(year = max(year), x = x[2], y = y[1]) %>%
  select(-id)

输出如下:

Source: local data frame [2 x 3]

        year     x     y
       (chr) (dbl) (dbl)
1 1993-01-01     1     2
2 1994-01-01     4     3