【发布时间】:2020-01-27 23:34:00
【问题描述】:
我正在编写一份报告,该报告从一些文件中获取数据、制作数据透视表并计算在某个时间段内哪个id 处于“活动状态”。但是,我发现一些源文件存在数据丢失的问题,我需要修复它。
举个例子更容易解释:
所有文件都被导入到一个 tibble 中,如下所示:
df.data %>% head()
### A tibble: 6 x 2
## ID REPORT_DATE
## <chr> <date>
##1 9495 2019-08-14
##2 1678 2019-08-14
##3 0944 2019-08-14
##4 6046 2019-08-14
##5 7758 2019-08-14
##6 2403 2019-08-14
导入后,我创建了一个如下所示的数据透视表:
df.pivot <- df.data %>% select(ID, REPORT_DATE) %>%
mutate(IN_REPORT=1) %>% arrange(ID, REPORT_DATE) %>%
spread(REPORT_DATE, IN_REPORT, fill=0) %>% head()
print(df.pivot %>% head)
### A tibble: 6 x 8
## ID `2019-08-14` `2019-08-21` `2019-08-28` `2019-09-04` `2019-09-11` `2019-09-18` `2019-09-25`
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##1 8123 1 1 1 1 1 1 1
##2 0236 1 1 1 1 1 1 1
##3 0624 1 1 1 1 1 1 1
##4 1278 1 1 1 1 1 1 1
##5 2870 1 1 1 0 0 0 0
##6 5469 1 1 1 1 1 1 1
列中的值1 表示该ID 是“活着的”,而值0 表示该ID 是“不活跃的”(因为它还没有“出生”或因为它已经“死”了)
如果每个“活着的”ID 都出现在每个报告中,这将非常有用。但是,我发现有些 ID 丢失了,它们看起来像这样:
print(df.pivot %>%
filter(ID %in% c('3989', '4188', '9941', '8996')))
### A tibble: 4 x 8
## ID `2019-08-14` `2019-08-21` `2019-08-28` `2019-09-04` `2019-09-11` `2019-09-18` `2019-09-25`
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
##1 4188 1 1 0 0 1 1 1
##2 9941 1 1 1 0 1 1 1
##3 3989 1 0 0 1 1 1 1
##4 8996 1 1 1 0 0 0 1
我们以 ID 3989 为例:它出现在 2019-08-14 报告中,它缺少以下两个报告,然后在 2019-09-04 以后的报告中重新出现。
具体来说,我需要的是,对于每一行:
- 检查是否有
1, 0, 1类型的序列(其中可以有任意数量的零。 - 将值
1分配给找到的任何中间零
我已经成功地找到了使用这个问题的 ID(可能不是一个优雅的解决方案,但我认为它有效):
df.ids_with_issues <- NULL
for(t in 2:(ncol(df.pivot)-1)) {
df.temp <- df.pivot %>%
filter(
.[t]==1,
.[t+1]==0,
pmap_dbl(.[(t+1):ncol(df.pivot)], max)==1
) %>% select(ICCID)
if(is.null(df.ids_with_issues)) {
df.ids_with_issues <- df.temp
} else {
df.ids_with_issues <- df.ids_with_issues %>% union(df.temp)
}
}
print(df.ids_with_issues)
### A tibble: 4 x 1
## ICCID
## <chr>
##1 3989
##2 4188
##3 9941
##4 8996
但是我还没有找到解决方案的第二步如何处理。
你能指点我吗?
我认为可能可行的方法:
- 将行添加到源 tibble (
df.data) 以确保存在与有问题的 ID 对应的记录。
我宁愿不这样做,因为它会强制重新处理输入,虽然现在数据很小,但预计很快就会增长。
【问题讨论】: