如何将年度数据包含在每月数据集中

时间:2019-09-04 10:28:32

标签: r database time-series na zoo

我正在尝试将年度公司数据添加到每月的数据中。由于年度数据是在特定月份报告的,并不总是每12个月更新一次,因此我需要将年度值与月度数据集中的月份相匹配,然后将其延续到该特定公司的下一个可用数据点(如果有)。

数据集由数千个具有唯一ID的公司组成,这些ID通常不会以相同的年度模式进行报告。随后的两个ReportMonths不必在同一个月。另外,可能有些年份我没有ReportMonth,因此该年份没有年度数据。

我确保在每个月都有一些年度数据时,年度变量的整行都不会是NA。下面是该结构的示例以及我现在所处的位置。

        id     Date  MonVariable  ReportMonth  AnnVariable
1  ABCDEFG  1999-02            1         <NA>         <NA>
2  ABCDEFG  1999-01            2         <NA>         <NA>
3  ABCDEFG  1998-12            3         <NA>         <NA>
4  HIJKLMN  2019-08            4         <NA>         <NA>
5  HIJKLMN  2019-07            5         <NA>         <NA>
6  HIJKLMN  2019-06            6         <NA>         <NA>
7  HIJKLMN  2019-05            7      2019-05          101
8  HIJKLMN  2019-04            8      2018-06          113

我尝试对每个年度变量使用dplyr:group_by(id),然后使用zoo:na.locf(x, na.rm = F, fromLast = T, maxgap = 12)

我最多可以保留12个月,这可以在第8行中看到,该行的年度变量从大约一年前的报告日期开始。

但是有两个问题。第一个是从一个公司到另一个公司的转折,下面该公司的最新值仍然缺失(第4-6行)。但是,我也想为他们提供最后可用的价值,如下所示。

        id     Date  MonVariable  ReportMonth  AnnVariable
1  ABCDEFG  1999-02            1         <NA>         <NA>
2  ABCDEFG  1999-01            2         <NA>         <NA>
3  ABCDEFG  1998-12            3         <NA>         <NA>
4  HIJKLMN  2019-08            4      2019-05          101
5  HIJKLMN  2019-07            5      2019-05          101
6  HIJKLMN  2019-06            6      2019-05          101
7  HIJKLMN  2019-05            7      2019-05          101
8  HIJKLMN  2019-04            8      2018-06          113

我认为na.locf直到休息时才填满,因为公司的最后年度变量通常也缺失,因此最接近的2个值的行之间的“间隙”大于12(猜猜dplyr分组到目前为止还无法达到我的理解。

第二个问题是,对于一家特定公司而言,所报告的年度价值之间的差距大于12个月。同样,na.locf也不会填充任何内容,因为差距大于maxgap。在这种情况下,我希望将最后一个可用值结转至以下12个月。

         id     Date  MonVariable  ReportMonth  AnnVariable
 1  HIJKLMN  2019-08            1      2019-08          149
 2  HIJKLMN  2019-07            2         <NA>         <NA>
 3  HIJKLMN  2019-06            3         <NA>         <NA>
 4  HIJKLMN  2019-05            4      2018-05          101
 5  HIJKLMN  2019-04            5      2018-05          101
 6  HIJKLMN  2019-03            6      2018-05          101
 7  HIJKLMN  2019-02            7      2018-05          101
 8  HIJKLMN  2019-01            8      2018-05          101
 9  HIJKLMN  2018-12            9      2018-05          101
10  HIJKLMN  2018-11            1      2018-05          101
11  HIJKLMN  2018-10            2      2018-05          101
12  HIJKLMN  2018-09            3      2018-05          101
13  HIJKLMN  2018-08            4      2018-05          101
14  HIJKLMN  2018-07            5      2018-05          101
15  HIJKLMN  2018-06            6      2018-05          101
16  HIJKLMN  2018-05            7      2018-05          101
17  HIJKLMN  2018-04            8      2017-06          113

谢谢您的帮助!

1 个答案:

答案 0 :(得分:0)

您可以使用/cars/some-kind-of-post-title将数据拆分为ID,然后在by月份和substring月份之外进行"05"。请检查ifelse是否可用,否则请分配NA。对于"AnnVariable",我们可以使用已排序的"ReportMonth"作为标签,从"AnnVariable"中得出一个因子(应按您的数据进行扩展,但是请仔细检查,例如,"AnnVariable"是否按在您的示例中显示)。

df1 <- within(df1, {
  ReportMonth <- do.call(c, by(df1, df1$id, function(s) {
    r <- ifelse(as.numeric(substring(s$Date, 6)) >= 5, 
                paste0(substr(s$Date, 1, 4), "-05"),
                paste0(as.numeric(substr(s$Date, 1, 4)) - 1, "-05"))
    return(ifelse(r %in% s$ReportMonth, r, NA))
  }))
  AnnVariable <- factor(ReportMonth, labels=sort(as.numeric(na.omit(AnnVariable))))
})
df1
#        id    Date MonVariable ReportMonth AnnVariable
# 1 ABCDEFG 1999-02           1        <NA>        <NA>
# 2 ABCDEFG 1999-01           2        <NA>        <NA>
# 3 ABCDEFG 1998-12           3        <NA>        <NA>
# 4 HIJKLMN 2019-08           4     2019-05         100
# 5 HIJKLMN 2019-07           5     2019-05         100
# 6 HIJKLMN 2019-06           6     2019-05         100
# 7 HIJKLMN 2019-05           7     2019-05         100
# 8 HIJKLMN 2019-04           8     2018-05          90

编辑

如果时间变化更为复杂,您可以考虑将日期转换为cut的{​​{1}}。

numeric

数据

df1[8, 4] <- "2018-06"

# helping variables
df1$Date.num <- as.numeric(gsub("\\D", "", df1$Date))
df1$ReportMonth.num <- as.numeric(gsub("\\D", "", df1$ReportMonth))

df1 <- within(df1, {
  ReportMonth <- do.call(c, by(df1, df1$id, function(s) {
    n <- rev(na.omit(s$ReportMonth))
    res <- cut(s$Date.num, c(gsub("\\D", "", n), range(s$Date.num)), labels=c(n, n[2]))
    return(as.character(res))
  }))
  AnnVariable <- factor(ReportMonth, labels=sort(as.numeric(na.omit(AnnVariable))))
})[1:5]
#        id    Date MonVariable ReportMonth AnnVariable
# 1 ABCDEFG 1999-02           1        <NA>        <NA>
# 2 ABCDEFG 1999-01           2        <NA>        <NA>
# 3 ABCDEFG 1998-12           3        <NA>        <NA>
# 4 HIJKLMN 2019-08           4     2019-05         100
# 5 HIJKLMN 2019-07           5     2019-05         100
# 6 HIJKLMN 2019-06           6     2019-05         100
# 7 HIJKLMN 2019-05           7     2019-05         100
# 8 HIJKLMN 2019-04           8     2018-06          90