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

时间:2016-05-01 20:25:36

标签: r match lookup

我合并了从不同来源下载的数据。数据是年度的(每年一次观察),但日期不是一直“锚定”,例如我有“1992-12-31”或“1993-01-01”。处理此类数据的推荐方法是什么? 如何最好地合并data.frame中的某些行,基于日期中“贴近度”的标准?

关于合并数据框中的行存在问题和答案,这可以应用于我的情况并进行一些调整,但这里我的问题是特定于日期和处理“1992-12-31”共存的问题年度数据中的“1992 - 01 - 01” - 我的数据来自经合组织,国际货币基金组织,世界银行等机构。也许一个聪明的方案已经知道这些机构的标准惯例?

我对代码的效率和可读性感兴趣。我也对data.table解决方案非常开放。相关问题/答案没有具体关于日期: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))

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

也许为所有日期添加一天,然后将日期四舍五入到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