[英]Flag rows between two values of a column in a group using dplyr
我有如下的虚拟数据
df = data.frame(name = c(rep("Anna",8),rep("Jenny",7)),
id = c(100,100,100,100,100,100,100,100,250,250,250,250,250,250,250),
time = c("t2","t3","t5","t1","t7","t2","t1","t5","t1","t2","t6","t2","t8","t6","t5"), stringsAsFactors = F)
> df
name id time
1 Anna 100 t2
2 Anna 100 t3
3 Anna 100 t5
4 Anna 100 t1
5 Anna 100 t7
6 Anna 100 t2
7 Anna 100 t1
8 Anna 100 t5
9 Jenny 250 t1
10 Jenny 250 t2
11 Jenny 250 t6
12 Jenny 250 t2
13 Jenny 250 t8
14 Jenny 250 t6
15 Jenny 250 t5
我的预期输出是,对于每个id
组,我想使用time
变量来flag
t2和t5之间(包括t2和t5)的值-每个组中都会有多种情况,并且代码应能够排除某些破损情况,例如下面的例子
> df
name id time Flag
1 Anna 100 t2 1
2 Anna 100 t3 1
3 Anna 100 t5 1
4 Anna 100 t1 0
5 Anna 100 t7 0
6 Anna 100 t2 1
7 Anna 100 t1 1
8 Anna 100 t5 1
9 Jenny 250 t1 0
10 Jenny 250 t2 0
11 Jenny 250 t6 0
12 Jenny 250 t2 1
13 Jenny 250 t8 1
14 Jenny 250 t6 1
15 Jenny 250 t5 1
我要求使用dplyr()
模式,因为我将来可以添加更多分组变量以实现可伸缩性。 我搜索了如何在dplyr函数中使用which()
,但没有得到太多结果,我在这里找到了一个等效的python 使用Python获取列的两个值之间的行
Edit1:每个组中有多个t2-t5部分需要标记。 感谢@ronak提出来
提前致谢
应该有一个更好的选择,但这可行
library(tidyverse)
df %>%
group_by(name) %>%
mutate(flag = +(row_number() %in% which(time == "t2"):which(time == "t5")))
# name id time flag
# <chr> <dbl> <chr> <dbl>
#1 Anna 100 t2 1
#2 Anna 100 t3 1
#3 Anna 100 t5 1
#4 Jenny 250 t1 0
#5 Jenny 250 t2 1
#6 Jenny 250 t3 1
#7 Jenny 250 t4 1
#8 Jenny 250 t5 1
假设每个组中只有一个“ t2”和“ t5”。
使用基本ave
逻辑相同
as.numeric(with(df, ave(time, name, FUN = function(x)
+(1:length(x) %in% which(x == "t2"):which(x == "t5")))))
#[1] 1 1 1 0 1 1 1 1
编辑
如果您有多个“ t2”和“ t5”,则无需考虑组,因为您仍然要标记它们。 我们可以使用mapply
并创建一个索引序列以将flag标记为1。
df$flag <- 0
df$flag[unlist(mapply(":", which(df$time == "t2"), which(df$time == "t5")))] <- 1
和相同的dplyr
版本是
df %>%
mutate(flag = +(row_number() %in%
unlist(map2(which(time == "t2"), which(time == "t5"), seq))))
以下是您可以考虑的一种简单方法:
library(dplyr)
df %>%
mutate(flag = ifelse(time %in% c("t2", "t3", "t4", "t5"), 1, 0))
这将标记您所描述的数据并且可读。
name id time flag
1 Anna 100 t2 1
2 Anna 100 t3 1
3 Anna 100 t5 1
4 Jenny 250 t1 0
5 Jenny 250 t2 1
6 Jenny 250 t3 1
7 Jenny 250 t4 1
8 Jenny 250 t5 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.