如何标记r中列中两个特定字符值之间的所有行? 问题描述
如何标记r中列中两个特定字符值之间的所有行? 问题描述,r,R,frame_type列(下方)中的start和end指的是车辆换道的开始和结束。对于驱动程序的每个id,我希望在一个新列中从头到尾将所有行标记为“LC” 资料 我搜索了很多,但没有找到任何解决这个问题的方法。我所知道的最接近的东西是tidyr::fill(),但在这种情况下不起作用。我想使用dplyr::group_by(),因为有几个ids。请帮助。我们可以使用数据表。将'data.frame'转换为'data.table'(setDT(foo)),根据逻辑向量的累积和(frame\u typ
frame_type
列(下方)中的start
和end
指的是车辆换道的开始和结束。对于驱动程序的每个id
,我希望在一个新列中从头到尾将所有行标记为“LC”
资料
我搜索了很多,但没有找到任何解决这个问题的方法。我所知道的最接近的东西是
tidyr::fill()
,但在这种情况下不起作用。我想使用dplyr::group_by()
,因为有几个id
s。请帮助。我们可以使用数据表。将'data.frame'转换为'data.table'(setDT(foo)
),根据逻辑向量的累积和(frame\u type==“start”
)进行分组,如果任何
的'frame\u type'具有'start'字符串,则获取从'start'到'end'的位置序列的行索引(.I
),提取该列($V1
),使用它作为i
创建一个新的列“LC”,方法是粘贴字符串“LC”
,并将逻辑索引的累积和按“id”分组。如果需要,NA
值可以更改为
(不推荐)
库(data.table)
i1谢谢你!rle()
真的很有用。谢谢你的回答。它适用于这些示例数据,但对于我的原始数据,它抛出错误,其中(frame\u type==“start”):哪个(frame\u type==“end”):由于某种原因,参数长度为0
。@umairdurrani我已经处理了使用cumsum
的分组变量没有“开始”的情况。是否也有只有“结束”的情况
foo <- data.frame(id = c(rep(1, 20), rep(2, 10)),
frame_type = rep(c(".", ".", ".",
"start", ".", "lcf", ".",
".", "end", "."), 3))
> foo
id frame_type
1 1 .
2 1 .
3 1 .
4 1 start
5 1 .
6 1 lcf
7 1 .
8 1 .
9 1 end
10 1 .
11 1 .
12 1 .
13 1 .
14 1 start
15 1 .
16 1 lcf
17 1 .
18 1 .
19 1 end
20 1 .
21 2 .
22 2 .
23 2 .
24 2 start
25 2 .
26 2 lcf
27 2 .
28 2 .
29 2 end
30 2 .
> foo
id frame_type LC
1 1 . .
2 1 . .
3 1 . .
4 1 start LC1
5 1 . LC1
6 1 lcf LC1
7 1 . LC1
8 1 . LC1
9 1 end LC1
10 1 . .
11 1 . .
12 1 . .
13 1 . .
14 1 start LC2
15 1 . LC2
16 1 lcf LC2
17 1 . LC2
18 1 . LC2
19 1 end LC2
20 1 . .
21 2 . .
22 2 . .
23 2 . .
24 2 start LC1
25 2 . LC1
26 2 lcf LC1
27 2 . LC1
28 2 . LC1
29 2 end LC1
30 2 . .
library(data.table)
i1 <- setDT(foo)[ , if(any(frame_type == "start")) .I[which(frame_type ==
"start"):which(frame_type == "end")], cumsum(frame_type == "start")]$V1
foo[i1, LC := paste0("LC", cumsum(frame_type == "start")), id
][is.na(LC), LC := "."][]
# id frame_type LC
# 1: 1 . .
# 2: 1 . .
# 3: 1 . .
# 4: 1 start LC1
# 5: 1 . LC1
# 6: 1 lcf LC1
# 7: 1 . LC1
# 8: 1 . LC1
# 9: 1 end LC1
#10: 1 . .
#11: 1 . .
#12: 1 . .
#13: 1 . .
#14: 1 start LC2
#15: 1 . LC2
#16: 1 lcf LC2
#17: 1 . LC2
#18: 1 . LC2
#19: 1 end LC2
#20: 1 . .
#21: 2 . .
#22: 2 . .
#23: 2 . .
#24: 2 start LC1
#25: 2 . LC1
#26: 2 lcf LC1
#27: 2 . LC1
#28: 2 . LC1
#29: 2 end LC1
#30: 2 . .
do.call(rbind, lapply(split(foo, foo$id), function(a){
temp = inverse.rle(with(rle(cumsum(a$frame_type == "start") -
cumsum(head(c(FALSE, a$frame_type == "end"), -1))),
list(lengths = lengths,
values = replace(values, values == 1,
seq_along(values[values == 1])))))
a$LC = replace(paste0("LC", temp), temp == 0, ".")
a
}))
# id frame_type LC
#1.1 1 . .
#1.2 1 . .
#1.3 1 . .
#1.4 1 start LC1
#1.5 1 . LC1
#1.6 1 lcf LC1
#1.7 1 . LC1
#1.8 1 . LC1
#1.9 1 end LC1
#1.10 1 . .
#1.11 1 . .
#1.12 1 . .
#1.13 1 . .
#1.14 1 start LC2
#1.15 1 . LC2
#1.16 1 lcf LC2
#1.17 1 . LC2
#1.18 1 . LC2
#1.19 1 end LC2
#1.20 1 . .
#2.21 2 . .
#2.22 2 . .
#2.23 2 . .
#2.24 2 start LC1
#2.25 2 . LC1
#2.26 2 lcf LC1
#2.27 2 . LC1
#2.28 2 . LC1
#2.29 2 end LC1
#2.30 2 . .