每季度替换缺失的季度和缺失的数据
Replacing missing quarter and missing data per quarter
背景
我有一个季度数据集,其中缺少某些季度和相应的值。数据集的特点是:
- 每组应该相同数量的四分之一,但实际上缺少四分之一
- 对于缺失的季度值未知
- 这将通过采购估算下一个可用值来解决;例如,可通过
na.locf
函数
示例数据
# Packages
Vectorize(require)(package = c("tidyverse", "zoo", "magrittr"),
character.only = TRUE)
# Seed
set.seed(123)
# Dummy data
dta <- data.frame(group = rep(LETTERS[1:5], 10)) %>%
group_by(group) %>%
mutate(qrtr = seq(
from = as.Date("01/01/2012", "%d/%m/%Y"),
to = as.Date("31/5/2014", "%d/%m/%Y"),
by = "quarter"
)) %>%
ungroup() %>%
mutate(qrtr = as.yearqtr(qrtr)) %>%
arrange(group, qrtr) %>%
mutate(value = sample(1:10, 50, replace = TRUE))
# Remove random rows
dta[sample(1:dim(dta)[1], 10), c(2, 3)] <- NA
dta %<>% na.omit()
预览
# A tibble: 40 x 3
group qrtr value
<chr> <S3: yearqtr> <int>
1 A 2012 Q1 3
2 A 2012 Q2 8
3 A 2012 Q4 9
4 A 2013 Q1 10
5 A 2013 Q3 6
6 A 2013 Q4 9
7 A 2014 Q1 6
8 B 2012 Q1 10
9 B 2012 Q2 5
10 B 2012 Q3 7
# ... with 30 more rows
问题
在缺少四分之一的每个组中创建添加行。在现有代码的上下文中,季度总数从序列 min(qrtr)
到 max(qrtr)
得出:
seq(from = as.Date("01/01/2012", "%d/%m/%Y"),
to = as.Date("31/5/2014", "%d/%m/%Y"),
by = "quarter")
第一个非缺失值应为缺失值结转
想要的结果:
>> dta
# A tibble: 50 x 3
group qrtr value
<chr> <S3: yearqtr> <int>
1 A 2012 Q1 3
2 A 2012 Q2 8
3 A 2012 Q3 8
4 A 2012 Q4 9
5 A 2013 Q1 10
6 A 2013 Q2 10
7 A 2013 Q3 6
8 A 2013 Q4 9
9 A 2014 Q1 6
10 A 2015 Q1 6
# ... with 40 more rows
提议的方法
一种方法依赖于使用 expand
,以便将隐式缺失值转换为显式缺失值。到目前为止,这会创建缺失的季度,但没有明确的方法可以为缺少给定季度的 value
列创建缺失的观察值。
dta %>%
# Append mixing quarters
expand(group, qrtr) %>%
left_join(data.frame(qrtr = as.yearqtr(
seq(
from = as.Date("01/01/2012", "%d/%m/%Y"),
to = as.Date("31/5/2014", "%d/%m/%Y"),
by = "quarter"
)
)), by = "qrtr") %>%
# TODO
# mutate(value = na.locf(value)) %>%
arrange(group, qrtr) -> dta_fixed
您似乎对padr
感兴趣
library(padr)
library(zoo)
#convert to POSIXct as pad() expect it to be like this
dta$qrtr <- as.POSIXct(dta$qrtr,format="%Y %q")
dta %>%
pad(group="group") %>%
arrange(group, qrtr) %>%
mutate(qrtr = as.yearqtr(qrtr)) %>%
na.locf()
输出为:
# A tibble: 49 x 3
group qrtr value
<chr> <chr> <chr>
1 A 2012 Q1 3
2 A 2012 Q2 8
3 A 2012 Q3 8
4 A 2012 Q4 9
5 A 2013 Q1 10
6 A 2013 Q2 10
7 A 2013 Q3 6
8 A 2013 Q4 9
9 A 2014 Q1 6
10 B 2012 Q1 10
# ... with 39 more rows
使用read.zoo
创建多变量时间序列z
,每组一列;将其与零宽度系列的四分之一 运行 na.locf
合并,然后将其转换回长格式。
我们可以省略:
- 带有
merge
的行,如果每个组都没有遗漏四分之一——在问题的示例数据中就是这种情况。即对于问题中的数据,我们可以省略 merge
(尽管如果我们将其保留在其中不会造成问题)
- 最后一行(带
fortify.zoo
的那一行)如果我们可以直接使用 10 x 5 多元时间序列 z
,这实际上可能更方便,例如library(ggplot); autoplot(z, facet = NULL) + scale_x_yearqtr()
或没有 facet
参数的相同参数将使用 ggplot2 图形使用 1 或 5 个面板绘制它。
这不使用问题尚未使用的任何包,而是直接使用原始 "yearqtr"
class 中的索引,无需转换。
library(zoo)
z <- read.zoo(dat, index = "qrtr", split = "group")
z <- merge(z, zoo(, seq(start(z), end(z), 1/4))
z <- na.locf(z)
fortify.zoo(z, melt = TRUE)
这也可以表示为以下管道:
library(dplyr) # or library(magrittr)
library(zoo)
dta %>%
read.zoo(index = "qrtr", split = "group") %>%
merge(zoo(, start(z), end(z), 1/4)) %>%
na.locf %>%
fortify.zoo(melt = TRUE)
更新 添加了管道并进行了一些措辞改进和澄清。
背景
我有一个季度数据集,其中缺少某些季度和相应的值。数据集的特点是:
- 每组应该相同数量的四分之一,但实际上缺少四分之一
- 对于缺失的季度值未知
- 这将通过采购估算下一个可用值来解决;例如,可通过
na.locf
函数
- 这将通过采购估算下一个可用值来解决;例如,可通过
示例数据
# Packages
Vectorize(require)(package = c("tidyverse", "zoo", "magrittr"),
character.only = TRUE)
# Seed
set.seed(123)
# Dummy data
dta <- data.frame(group = rep(LETTERS[1:5], 10)) %>%
group_by(group) %>%
mutate(qrtr = seq(
from = as.Date("01/01/2012", "%d/%m/%Y"),
to = as.Date("31/5/2014", "%d/%m/%Y"),
by = "quarter"
)) %>%
ungroup() %>%
mutate(qrtr = as.yearqtr(qrtr)) %>%
arrange(group, qrtr) %>%
mutate(value = sample(1:10, 50, replace = TRUE))
# Remove random rows
dta[sample(1:dim(dta)[1], 10), c(2, 3)] <- NA
dta %<>% na.omit()
预览
# A tibble: 40 x 3
group qrtr value
<chr> <S3: yearqtr> <int>
1 A 2012 Q1 3
2 A 2012 Q2 8
3 A 2012 Q4 9
4 A 2013 Q1 10
5 A 2013 Q3 6
6 A 2013 Q4 9
7 A 2014 Q1 6
8 B 2012 Q1 10
9 B 2012 Q2 5
10 B 2012 Q3 7
# ... with 30 more rows
问题
在缺少四分之一的每个组中创建添加行。在现有代码的上下文中,季度总数从序列
min(qrtr)
到max(qrtr)
得出:seq(from = as.Date("01/01/2012", "%d/%m/%Y"), to = as.Date("31/5/2014", "%d/%m/%Y"), by = "quarter")
第一个非缺失值应为缺失值结转
想要的结果:
>> dta
# A tibble: 50 x 3
group qrtr value
<chr> <S3: yearqtr> <int>
1 A 2012 Q1 3
2 A 2012 Q2 8
3 A 2012 Q3 8
4 A 2012 Q4 9
5 A 2013 Q1 10
6 A 2013 Q2 10
7 A 2013 Q3 6
8 A 2013 Q4 9
9 A 2014 Q1 6
10 A 2015 Q1 6
# ... with 40 more rows
提议的方法
一种方法依赖于使用 expand
,以便将隐式缺失值转换为显式缺失值。到目前为止,这会创建缺失的季度,但没有明确的方法可以为缺少给定季度的 value
列创建缺失的观察值。
dta %>%
# Append mixing quarters
expand(group, qrtr) %>%
left_join(data.frame(qrtr = as.yearqtr(
seq(
from = as.Date("01/01/2012", "%d/%m/%Y"),
to = as.Date("31/5/2014", "%d/%m/%Y"),
by = "quarter"
)
)), by = "qrtr") %>%
# TODO
# mutate(value = na.locf(value)) %>%
arrange(group, qrtr) -> dta_fixed
您似乎对padr
library(padr)
library(zoo)
#convert to POSIXct as pad() expect it to be like this
dta$qrtr <- as.POSIXct(dta$qrtr,format="%Y %q")
dta %>%
pad(group="group") %>%
arrange(group, qrtr) %>%
mutate(qrtr = as.yearqtr(qrtr)) %>%
na.locf()
输出为:
# A tibble: 49 x 3
group qrtr value
<chr> <chr> <chr>
1 A 2012 Q1 3
2 A 2012 Q2 8
3 A 2012 Q3 8
4 A 2012 Q4 9
5 A 2013 Q1 10
6 A 2013 Q2 10
7 A 2013 Q3 6
8 A 2013 Q4 9
9 A 2014 Q1 6
10 B 2012 Q1 10
# ... with 39 more rows
使用read.zoo
创建多变量时间序列z
,每组一列;将其与零宽度系列的四分之一 运行 na.locf
合并,然后将其转换回长格式。
我们可以省略:
- 带有
merge
的行,如果每个组都没有遗漏四分之一——在问题的示例数据中就是这种情况。即对于问题中的数据,我们可以省略merge
(尽管如果我们将其保留在其中不会造成问题) - 最后一行(带
fortify.zoo
的那一行)如果我们可以直接使用 10 x 5 多元时间序列z
,这实际上可能更方便,例如library(ggplot); autoplot(z, facet = NULL) + scale_x_yearqtr()
或没有facet
参数的相同参数将使用 ggplot2 图形使用 1 或 5 个面板绘制它。
这不使用问题尚未使用的任何包,而是直接使用原始 "yearqtr"
class 中的索引,无需转换。
library(zoo)
z <- read.zoo(dat, index = "qrtr", split = "group")
z <- merge(z, zoo(, seq(start(z), end(z), 1/4))
z <- na.locf(z)
fortify.zoo(z, melt = TRUE)
这也可以表示为以下管道:
library(dplyr) # or library(magrittr)
library(zoo)
dta %>%
read.zoo(index = "qrtr", split = "group") %>%
merge(zoo(, start(z), end(z), 1/4)) %>%
na.locf %>%
fortify.zoo(melt = TRUE)
更新 添加了管道并进行了一些措辞改进和澄清。