R 根据日期将数据框拆分为行
我有两个数据帧:R 根据日期将数据框拆分为行,r,R,我有两个数据帧: d1 <- data.frame(id=1,a=1,start_d1=10, end_d1=19) d2 <- data.frame(id=1,b=2, start_d2=15, end_d2=24) 我现在正在做的是:我在id上加入d1和d2,以获得d。 然后,我对d中的每一行应用我编写的显式函数,该函数使用新变量start和end将行拆分为新的行,具体取决于重叠 这有点乱。有没有一种更简单的方法来解决我的问题?我认为,将两个数据集连接起来,然后应用函数行上升,
d1 <- data.frame(id=1,a=1,start_d1=10, end_d1=19)
d2 <- data.frame(id=1,b=2, start_d2=15, end_d2=24)
我现在正在做的是:我在id
上加入d1
和d2
,以获得d
。
然后,我对d
中的每一行应用我编写的显式函数,该函数使用新变量start
和end
将行拆分为新的行,具体取决于重叠
这有点乱。有没有一种更简单的方法来解决我的问题?我认为,将两个数据集连接起来,然后应用函数行上升,然后用
do.call将它们绑定起来似乎是一种合理的方法
我试图想出一个dplyr
方法,但它感觉更像是一个讨厌的东西,而不是其他任何东西
d1 <- data.frame(id=c(1,2),a=1, start_d1=c(10,20), end_d1=c(19,29))
d2 <- data.frame(id=c(1,2),b=2, start_d2=c(15,25), end_d2=c(24,34))
full_join(d1,d2) %>%
rowwise() %>%
do(data.frame(id = .$id,
all_seq = seq(.$start_d1, .$end_d2, by = 1),
a = c(rep(.$a, length(seq(.$start_d1, .$end_d1, by =1))),
rep(NA, length(seq(.$end_d1+1, .$end_d2, by = 1)))),
b = c(rep(NA, length(seq(.$start_d1+1, .$start_d2, by =1))),
rep(.$b, length(seq(.$start_d2, .$end_d2, by = 1)))))) %>%
mutate(classifier = case_when(!is.na(a) && is.na(b) ~ 1,
!is.na(a) && !is.na(b) ~ 2,
is.na(a) && !is.na(b) ~ 3
)) %>%
ungroup() %>%
group_by(id, classifier) %>%
summarise(start = min(all_seq),
end = max(all_seq),
a = unique(a),
b = unique(b)) %>%
select(-classifier)
Joining, by = "id"
# A tibble: 6 x 5
# Groups: id [2]
id start end a b
<dbl> <dbl> <dbl> <dbl> <dbl>
1 1 10 14 1 NA
2 1 15 19 1 2
3 1 20 24 NA 2
4 2 20 24 1 NA
5 2 25 29 1 2
6 2 30 34 NA 2
d1%
do(data.frame(id=.$id,
所有顺序=顺序(.$start\U d1,.$end\U d2,by=1),
a=c(代表(.$a,长度(顺序(.$start_d1,.$end_d1,by=1)),
代表(不适用,长度(序号(.$end_d1+1,.$end_d2,by=1)),
b=c(代表(NA,长度(序号(.$start_d1+1,.$start_d2,by=1)),
代表(.$b,长度(序号(.$start_d2,.$end_d2,by=1щщщ))%>%
当(!is.na(a)&&is.na(b)~1,
!is.na(a)&!is.na(b)~2,
is.na(a)&!is.na(b)~3
)) %>%
解组()%>%
分组依据(id,分类器)%>%
总结(开始=分钟(全部),
结束=最大值(全部),
a=唯一(a),
b=唯一(b))%>%
选择(-分类器)
通过=“id”加入
#一个tibble:6x5
#组别:id[2]
我从a到b
1114141NA
2 1 15 19 1 2
3 1 20 24 NA 2
420241NA
5 2 25 29 1 2
6 2 30 34 NA 2
do
-函数的思想是根据id
生成整个周期的序列,并且a
和b
在它们必须的位置。我认为,连接两个数据集,然后应用函数行上升,然后rbind
用do.call调用它们似乎是一种合理的方法
我试图想出一个dplyr
方法,但它感觉更像是一个讨厌的东西,而不是其他任何东西
d1 <- data.frame(id=c(1,2),a=1, start_d1=c(10,20), end_d1=c(19,29))
d2 <- data.frame(id=c(1,2),b=2, start_d2=c(15,25), end_d2=c(24,34))
full_join(d1,d2) %>%
rowwise() %>%
do(data.frame(id = .$id,
all_seq = seq(.$start_d1, .$end_d2, by = 1),
a = c(rep(.$a, length(seq(.$start_d1, .$end_d1, by =1))),
rep(NA, length(seq(.$end_d1+1, .$end_d2, by = 1)))),
b = c(rep(NA, length(seq(.$start_d1+1, .$start_d2, by =1))),
rep(.$b, length(seq(.$start_d2, .$end_d2, by = 1)))))) %>%
mutate(classifier = case_when(!is.na(a) && is.na(b) ~ 1,
!is.na(a) && !is.na(b) ~ 2,
is.na(a) && !is.na(b) ~ 3
)) %>%
ungroup() %>%
group_by(id, classifier) %>%
summarise(start = min(all_seq),
end = max(all_seq),
a = unique(a),
b = unique(b)) %>%
select(-classifier)
Joining, by = "id"
# A tibble: 6 x 5
# Groups: id [2]
id start end a b
<dbl> <dbl> <dbl> <dbl> <dbl>
1 1 10 14 1 NA
2 1 15 19 1 2
3 1 20 24 NA 2
4 2 20 24 1 NA
5 2 25 29 1 2
6 2 30 34 NA 2
d1%
do(data.frame(id=.$id,
所有顺序=顺序(.$start\U d1,.$end\U d2,by=1),
a=c(代表(.$a,长度(顺序(.$start_d1,.$end_d1,by=1)),
代表(不适用,长度(序号(.$end_d1+1,.$end_d2,by=1)),
b=c(代表(NA,长度(序号(.$start_d1+1,.$start_d2,by=1)),
代表(.$b,长度(序号(.$start_d2,.$end_d2,by=1щщщ))%>%
当(!is.na(a)&&is.na(b)~1,
!is.na(a)&!is.na(b)~2,
is.na(a)&!is.na(b)~3
)) %>%
解组()%>%
分组依据(id,分类器)%>%
总结(开始=分钟(全部),
结束=最大值(全部),
a=唯一(a),
b=唯一(b))%>%
选择(-分类器)
通过=“id”加入
#一个tibble:6x5
#组别:id[2]
我从a到b
1114141NA
2 1 15 19 1 2
3 1 20 24 NA 2
420241NA
5 2 25 29 1 2
6 2 30 34 NA 2
do
-函数的思想是根据id
生成整个周期的序列,以及a
和b
它们必须在的位置。嗨,预期的输出是什么。请dput()
您的预期输出将是好的。类似这样的合并d@tushallad不,这并没有为开始和日期相关的重叠提供一个单独的行:您可以在删除数据帧名称中的所有after之后使用rbind
!您好,预期的输出是什么。请dput()
您的预期输出会很好。类似这样的merge
d@tushallad不,这并没有为开始和日期相关的重叠提供一个单独的行:您可以在删除数据帧名称中的所有after之后使用rbind
!