来自不同来源的年度数据在同一年有不同的日期
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 R
或 ggplot2
(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
我合并了从不同来源下载的数据。数据是年度数据(每年一次观察),但日期不一致 "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 R
或 ggplot2
(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