R:将隐式缺失值和组填充到数据的整个时间跨度
R: Fill in Implicit Missing Values and Groups to the Entire Time Span of the Data
Objective:
在数据的整个时间跨度内为每个 ID 和每个 组 填充隐式缺失值,包括完全缺失的 组 来自数据集。
背景:
每个 ID 都有几个组,每个组都应该有每天的值。但是,某些值缺少某些日期(例如 1b 2019-01-01),并且某些组在数据集中完全缺失(例如 2b)。
# A tibble: 8 x 4
ID group date value
<dbl> <chr> <chr> <dbl>
1 1 a 2019-01-01 1
2 1 a 2019-01-02 3
3 1 a 2019-01-03 4
4 1 b 2019-01-02 4
5 1 b 2019-01-03 5
6 2 a 2019-01-01 8
7 2 a 2019-01-02 9
8 2 a 2019-01-03 1
生成数据帧的代码
df <- tibble(ID = c(1, 1, 1, 1, 1, 2, 2, 2),
group = c('a', 'a', 'a', 'b', 'b', 'a', 'a', 'a'),
date = c('2019-01-01', '2019-01-02','2019-01-03', '2019-01-02', '2019-01-03', '2019-01-01', '2019-01-02', '2019-01-03'),
value = c(1, 3, 4, 4, 5, 8, 9, 1))
尝试 1:
library(tsibble)
df %>%
# tsibble format
as_tsibble(key = c(ID, group), index = date) %>%
# group by
group_by(ID, group) %>%
# fill gaps
fill_gaps(.full = TRUE)
尝试 2:
library(tidyverse)
complete(df, expand(df, nesting(ID, group), date = full_seq(date,1)))
两者产生相同的结果:请注意 组 2b 缺失
# A tsibble: 9 x 4 [1D]
# Key: ID, group [3]
# Groups: ID, group [3]
ID group date value
<dbl> <chr> <date> <dbl>
1 1 a 2019-01-01 1
2 1 a 2019-01-02 3
3 1 a 2019-01-03 4
4 1 b 2019-01-01 NA
5 1 b 2019-01-02 4
6 1 b 2019-01-03 5
7 2 a 2019-01-01 8
8 2 a 2019-01-02 9
9 2 a 2019-01-03 1
我希望输出是
# A tibble: 12 x 4
ID group date value
<dbl> <chr> <chr> <dbl>
1 1 a 2019-01-01 1
2 1 a 2019-01-02 3
3 1 a 2019-01-03 4
4 1 b 2019-01-01 NA
5 1 b 2019-01-02 4
6 1 b 2019-01-03 5
7 2 a 2019-01-01 8
8 2 a 2019-01-02 9
9 2 a 2019-01-03 1
10 2 b 2019-01-01 NA
11 2 b 2019-01-02 NA
12 2 b 2019-01-03 NA
其中 组 b,从数据集中隐式缺失,出现在结果中。
请注意,我的数据集有 800 万行,并且每天都在增长。该代码将每天执行,所以我真的很期待 快速 和执行任务的便捷方式。但欢迎任何想法或答案!
您可以创建一个数据框,其中包含 ID、组和日期的唯一值的笛卡尔积,然后将其与原始数据框合并以获得所需的结果。
zz <- merge(merge(unique(df$ID), unique(df$group), by = NULL, all = TRUE),
unique(df$date), by = NULL, all = TRUE)
merge(df, zz, by.x = c('ID','group', 'date'), by.y = c('x','y.x', 'y.y'), all = TRUE)
当然,如果您有大量组件和日期,它会很昂贵。在这种情况下,您可以首先将 ID/group 组合与您的原始数据框合并以获得仅缺失的组合,然后将其与日期集合并,如果您明白我的意思,则再次仅选择缺失的组合。
实际上您的第二次尝试非常接近您的预期,但需要将 nesting()
替换为 crossing()
。 nesting()
仅查找数据中出现的组合,但 crossing()
查找所有可能的组合。
library(tidyr)
df <- tibble(ID = c(1, 1, 1, 1, 1, 2, 2, 2),
group = c('a', 'a', 'a', 'b', 'b', 'a', 'a', 'a'),
date = as.Date(c('2019-01-01', '2019-01-02','2019-01-03', '2019-01-02', '2019-01-03', '2019-01-01', '2019-01-02', '2019-01-03')),
value = c(1, 3, 4, 4, 5, 8, 9, 1))
complete(df, expand(df, crossing(ID, group), date = full_seq(date, 1)))
#> # A tibble: 12 x 4
#> ID group date value
#> <dbl> <chr> <date> <dbl>
#> 1 1 a 2019-01-01 1
#> 2 1 a 2019-01-02 3
#> 3 1 a 2019-01-03 4
#> 4 1 b 2019-01-01 NA
#> 5 1 b 2019-01-02 4
#> 6 1 b 2019-01-03 5
#> 7 2 a 2019-01-01 8
#> 8 2 a 2019-01-02 9
#> 9 2 a 2019-01-03 1
#> 10 2 b 2019-01-01 NA
#> 11 2 b 2019-01-02 NA
#> 12 2 b 2019-01-03 NA
由 reprex package (v0.3.0)
于 2019-10-13 创建
Objective: 在数据的整个时间跨度内为每个 ID 和每个 组 填充隐式缺失值,包括完全缺失的 组 来自数据集。
背景: 每个 ID 都有几个组,每个组都应该有每天的值。但是,某些值缺少某些日期(例如 1b 2019-01-01),并且某些组在数据集中完全缺失(例如 2b)。
# A tibble: 8 x 4
ID group date value
<dbl> <chr> <chr> <dbl>
1 1 a 2019-01-01 1
2 1 a 2019-01-02 3
3 1 a 2019-01-03 4
4 1 b 2019-01-02 4
5 1 b 2019-01-03 5
6 2 a 2019-01-01 8
7 2 a 2019-01-02 9
8 2 a 2019-01-03 1
生成数据帧的代码
df <- tibble(ID = c(1, 1, 1, 1, 1, 2, 2, 2),
group = c('a', 'a', 'a', 'b', 'b', 'a', 'a', 'a'),
date = c('2019-01-01', '2019-01-02','2019-01-03', '2019-01-02', '2019-01-03', '2019-01-01', '2019-01-02', '2019-01-03'),
value = c(1, 3, 4, 4, 5, 8, 9, 1))
尝试 1:
library(tsibble)
df %>%
# tsibble format
as_tsibble(key = c(ID, group), index = date) %>%
# group by
group_by(ID, group) %>%
# fill gaps
fill_gaps(.full = TRUE)
尝试 2:
library(tidyverse)
complete(df, expand(df, nesting(ID, group), date = full_seq(date,1)))
两者产生相同的结果:请注意 组 2b 缺失
# A tsibble: 9 x 4 [1D]
# Key: ID, group [3]
# Groups: ID, group [3]
ID group date value
<dbl> <chr> <date> <dbl>
1 1 a 2019-01-01 1
2 1 a 2019-01-02 3
3 1 a 2019-01-03 4
4 1 b 2019-01-01 NA
5 1 b 2019-01-02 4
6 1 b 2019-01-03 5
7 2 a 2019-01-01 8
8 2 a 2019-01-02 9
9 2 a 2019-01-03 1
我希望输出是
# A tibble: 12 x 4
ID group date value
<dbl> <chr> <chr> <dbl>
1 1 a 2019-01-01 1
2 1 a 2019-01-02 3
3 1 a 2019-01-03 4
4 1 b 2019-01-01 NA
5 1 b 2019-01-02 4
6 1 b 2019-01-03 5
7 2 a 2019-01-01 8
8 2 a 2019-01-02 9
9 2 a 2019-01-03 1
10 2 b 2019-01-01 NA
11 2 b 2019-01-02 NA
12 2 b 2019-01-03 NA
其中 组 b,从数据集中隐式缺失,出现在结果中。
请注意,我的数据集有 800 万行,并且每天都在增长。该代码将每天执行,所以我真的很期待 快速 和执行任务的便捷方式。但欢迎任何想法或答案!
您可以创建一个数据框,其中包含 ID、组和日期的唯一值的笛卡尔积,然后将其与原始数据框合并以获得所需的结果。
zz <- merge(merge(unique(df$ID), unique(df$group), by = NULL, all = TRUE),
unique(df$date), by = NULL, all = TRUE)
merge(df, zz, by.x = c('ID','group', 'date'), by.y = c('x','y.x', 'y.y'), all = TRUE)
当然,如果您有大量组件和日期,它会很昂贵。在这种情况下,您可以首先将 ID/group 组合与您的原始数据框合并以获得仅缺失的组合,然后将其与日期集合并,如果您明白我的意思,则再次仅选择缺失的组合。
实际上您的第二次尝试非常接近您的预期,但需要将 nesting()
替换为 crossing()
。 nesting()
仅查找数据中出现的组合,但 crossing()
查找所有可能的组合。
library(tidyr)
df <- tibble(ID = c(1, 1, 1, 1, 1, 2, 2, 2),
group = c('a', 'a', 'a', 'b', 'b', 'a', 'a', 'a'),
date = as.Date(c('2019-01-01', '2019-01-02','2019-01-03', '2019-01-02', '2019-01-03', '2019-01-01', '2019-01-02', '2019-01-03')),
value = c(1, 3, 4, 4, 5, 8, 9, 1))
complete(df, expand(df, crossing(ID, group), date = full_seq(date, 1)))
#> # A tibble: 12 x 4
#> ID group date value
#> <dbl> <chr> <date> <dbl>
#> 1 1 a 2019-01-01 1
#> 2 1 a 2019-01-02 3
#> 3 1 a 2019-01-03 4
#> 4 1 b 2019-01-01 NA
#> 5 1 b 2019-01-02 4
#> 6 1 b 2019-01-03 5
#> 7 2 a 2019-01-01 8
#> 8 2 a 2019-01-02 9
#> 9 2 a 2019-01-03 1
#> 10 2 b 2019-01-01 NA
#> 11 2 b 2019-01-02 NA
#> 12 2 b 2019-01-03 NA
由 reprex package (v0.3.0)
于 2019-10-13 创建