所以我有一个看起来像这样的数据集:
industry<-rep(c("A","B","C","D"),4)
country<-c(rep("UK",4),rep("France",4),rep("Germany",4),rep("Italy",4))
day<-c(rep(6,16),rep(7,16),rep(8,16),rep(9,16),rep(10,16))
industry<-rep(industry,5)
country<-rep(country,5)
a<-data.frame(industry,country)
a<-data.frame(a,day)
a$open<-sample(c(0,1),size = nrow(a),replace = T)
a$initial_day[a$open==0]<-sample(c(3,4,5),size=nrow(a[a$open==0,]),replace = T)
它看起来很复杂,但事实并非如此。
+----------+---------+-----+------+-------------+
| industry | country | day | open | initial_day |
+----------+---------+-----+------+-------------+
| A | UK | 6 | 1 | NA |
| B | UK | 6 | 0 | 3 |
| C | UK | 6 | 1 | NA |
| D | UK | 6 | 0 | 3 |
| A | France | 6 | 0 | 3 |
| B | France | 6 | 0 | 5 |
| C | France | 6 | 0 | 5 |
| D | France | 6 | 1 | NA |
| A | Germany | 6 | 0 | 5 |
| B | Germany | 6 | 0 | 3 |
+----------+---------+-----+------+-------------+
基本上,我有5天的数据(为了简单起见,第6、7、8、9和10天(,关于一些不同国家的行业关闭。每天,我都有关于每个国家和每个国家内每个行业的数据。因此,如果它打开,则为1,如果它关闭,则为0。我想处理的是"最初的一天"专栏。我想使用该列来扩展数据帧。本专栏告诉你行业封锁实施的当天。但是,所有这些日期都早于"日期"列中的最早日期(3、4、5(。因此,我想通过创建新的日期并在这两天之间设置0来扩展数据框架。
例如,英国的B行业在第6天被封锁,而这次封锁从第3天开始。因此,我想通过在第3、4和5天为英国的行业B设置0来扩展数据框架。该面板需要保持平衡,因此它从最早的初始封锁日期开始。从未被封锁的行业将始终保持"1"。这有道理吗?我知道这是非常非常规的,但我们完全感谢您的任何帮助。
所以它会是这样的。
+-----+---------+----------+------+--+
| day | country | industry | open | |
+-----+---------+----------+------+--+
| 3 | UK | A | 1 | |
| 3 | UK | B | 1 | |
| 3 | UK | C | 1 | |
| 3 | UK | D | 1 | |
| 3 | France | A | 0 | |
| 3 | France | B | 0 | |
| 3 | France | C | 1 | |
| 3 | France | D | 1 | |
| 3 | Germany | A | 1 | |
| 3 | Germany | B | 0 | |
+-----+---------+----------+------+--+
例如,如果最初的一天对B行业来说都是NA,那么英国的B从未进入封锁状态,所以整个过程都是1:
+---------+----------+------+-----+--+
| country | industry | open | day | |
+---------+----------+------+-----+--+
| UK | B | 1 | 3 | |
| UK | B | 1 | 4 | |
| UK | B | 1 | 5 | |
| UK | B | 1 | 6 | |
| UK | B | 1 | 7 | |
| UK | B | 1 | 8 | |
| UK | B | 1 | 9 | |
| UK | B | 1 | 10 | |
+---------+----------+------+-----+--+
如果最初的一天是5,意味着B行业在第5天进入封锁状态,我需要它看起来像这样:
+---------+----------+------+-----+--+
| country | industry | open | day | |
+---------+----------+------+-----+--+
| UK | B | 1 | 3 | |
| UK | B | 1 | 4 | |
| UK | B | 1 | 5 | |
| UK | B | 0 | 6 | |
| UK | B | 0 | 7 | |
| UK | B | 0 | 8 | |
| UK | B | 1 | 9 | |
| UK | B | 1 | 10 | |
+---------+----------+------+-----+--+
以下是使用tidyverse
包实现此功能的一种方法:首先,
a %>% distinct(industry, country) %>%
crossing(day = 3:5) %>%
bind_rows(a) %>%
group_by(industry, country) %>%
mutate(initial_day = initial_day[!is.na(initial_day)][1],
open = case_when(!is.na(open) ~ open,
day <= initial_day ~ 1,
day > initial_day ~ 0)) %>%
ungroup %>%
arrange(industry, country, day)
首先,我使用crossing
函数创建缺少的天数(day = c(3, 4, 5)
(。我将这些天添加到数据帧中,然后填充day
和initial_day
的缺失值。由于initial_day
对于每个country
和industry
都具有唯一的值,因此很容易填充。
对于open
列,我检查day
是否小于或大于initial_day
。
结果如下:
# A tibble: 128 x 5
industry country day open initial_day
<chr> <chr> <dbl> <dbl> <dbl>
1 A France 3 1 5
2 A France 4 1 5
3 A France 5 1 5
4 A France 6 0 5
5 A France 7 0 5
6 A France 8 0 5
7 A France 9 0 5
8 A France 10 1 5
9 A Germany 3 1 3
10 A Germany 4 0 3