使用以下数据集:
id from to trip
1 1 A B <NA>
2 1 B C X
3 1 C D <NA>
4 1 D A X
5 2 B A X
6 2 A C <NA>
7 2 C D <NA>
每当我在旅程列上找到X时,我都会尝试拆分数据,以获得类似的结果(注意有一个新列):
id from to trip group
1 1 A B <NA> 1
2 1 B C X 1
3 1 C D <NA> 2
4 1 D A X 2
5 2 B A X 3
6 2 A C <NA> 4
7 2 C D <NA> 4
这意味着它通过观察/行,并且基于id和trip列,每次到达X时都会启动一个新的数字。
我已经尝试了group_by(df, id, trip)
的一些事情,但我总是没有与那个结构类似的结构。
有什么建议吗?
答案 0 :(得分:2)
此基本R方法适用于示例:
df$group <- c(1, head(cumsum(df$trip == "X") + 1, -1))
在示例中,它返回
df
id from to trip group
1 1 A B <NA> 1
2 1 B C X 1
3 1 C D <NA> 2
4 1 D A X 2
5 2 B A X 3
6 2 A C <NA> 4
7 2 C D <NA> 4
另外,在第一次观察是“X”的情况下,那么1将是第一个元素,2将是第二个元素,我认为这是期望的。
正如@manotheshark在提交中提到的,此解决方案不适用于NA值,因为cumsum
将在遇到第一个NA后返回NA。建议的解决方案是将df$trip == "X"
替换为is.na(df$trip)
,这将在存在NA的情况下返回正确的值。
答案 1 :(得分:0)
试试这个(如果你真的需要在行之后开始新组 X我认为你可以通过另一个shift()来实现这一点==“X”:
library(data.table)
set.seed(1)
na.zero <- function (x) {
x[is.na(x)] <- 0
return(x)
}
dt <- data.table(id = c(1,1,1,2,2,2),
from = sample(c("A", "B", "C", "D"), 6, replace = T),
to = sample(c("A", "B", "C", "D"), 6, replace = T),
trip = sample(c("X", NA), 6, replace = T))
dt[, group:=(cumsum(na.zero(trip=="X"))+cumsum(id-na.zero(shift(id, 1L,type = 'lag'))))]
id from to trip group
1: 1 B D NA 1
2: 1 B C X 2
3: 1 C C NA 2
4: 2 D A X 4
5: 2 A A NA 4
6: 2 D A NA 4