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

R 不同来源的年度数据在同一年有不同的日期,r,match,lookup,R,Match,Lookup,我合并了从不同来源下载的数据。数据为年度数据(每年观察一次),但日期并非始终“固定”,例如,我有“1992-12-31”或“1993-01-01”。处理此类数据的推荐方法是什么如何根据日期中的“接近度”标准,最好地合并data.frame中的某些行? 关于在一个数据框架内合并行,存在一些问题和答案,这些问题可以在某种程度上适用于我的情况,但这里我的问题是特定于日期以及处理年度数据中“1992-12-31”和“1992-01-01”共存的问题——我的数据来自经合组织、国际货币基金组织、,世界银行。

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

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

我对代码的效率和可读性都感兴趣。我对data.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
    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
(假设像这样的映射“1992-12-31”=“1993-01-01”)

解决方案:

    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
    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

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

使用library
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

或者更一般地说,
df%>%group\u by(year=格式(如日期(year)+1、%Y-%m-01”)%%>%summary\u(funs(sum(,na.rm=TRUE))
@DavidArenburg同意,我们可以美化它,使它更有效,等等。我只是想推销一个想法,将日期四舍五入到月份。谢谢您的快速回复。我不熟悉dplyr,但它似乎适合这种操作。你的答案很容易理解。我将在我的数据上处理这个问题,如果我没有遇到意外问题,我将在几天后回来解决这个问题。:-)谢谢你的快速回复。因此,这里的关键步骤是
mutate
,它包含一组函数
difftime()
lead()
,以及
max(year)
参数。这一条线不容易理解,但在把它分解之后,它是有意义的。由于不熟悉dplyr,我需要对它进行一些处理。谢谢你的帮助!关于R和R中的大多数包函数,最好的部分是,您可以分别计算代码的每一部分,并查看发生了什么。例如,您可以将
difftime
与其他内容分开计算。然后,你可以计算出cumsum,看看你得到了什么,等等……真的谢谢!您能否评论一下您的解决方案与zx8754之间的差异?您的解决方案较长,但不依赖于软件包lubridate,例如,在健壮性方面是否存在差异(例如,如果使用12月31日以外的日期,例如6月1日,您的代码是否仍然有效?【我将尽快测试所有这些,但今天是劳动节】如果你认为这会增加价值的话,也许你可以对此进行评论,并在回答的正文中细分步骤。谢谢您可以在您的数据集上尝试这两种方法,并查看哪一种方法在做什么以及它与您的数据的匹配程度。我不能说一个比另一个好。此解决方案将连续日期分组。另一种解决方案是将一个日期滚动到下一个月,对一个月内的所有日期进行分组并求和x/y。根据您提供的数据之外的其他内容,一个可能比另一个更好。