我在R中有data.table
跟踪系统中项目的移动。我想根据两个字段ID
和Location
对这些数据进行分组。
library(data.table)
example <- data.table(ID = rep(LETTERS[1:3], each = 6),
Location = c(1,2,3,1,2,1,2,2,2,3,3,1,2,3,3,3,1,3))
example
# ID Location
# 1: A 1
# 2: A 2
# 3: A 3
# 4: A 1
# 5: A 2
# 6: A 1
# 7: B 2
# 8: B 2
# 9: B 2
# 10: B 3
# 11: B 3
# 12: B 1
# 13: C 2
# 14: C 3
# 15: C 3
# 16: C 3
# 17: C 1
# 18: C 3
我希望输出的是一个新列,其数字在每次位置更改时递增,而不管新位置是什么(即,如果该位置存在于历史记录中的其他位置)。而是与this question相反,它仅在组内递增。
expected_output <- data.table(ID = rep(LETTERS[1:3], each = 6),
Location = c(1,2,3,1,2,1,2,2,2,3,3,1,2,3,3,3,1,3),
Group = c(1,2,3,4,5,6,1,1,1,2,2,3,1,2,2,2,3,4))
expected_output
# ID Location Group
# 1: A 1 1
# 2: A 2 2
# 3: A 3 3
# 4: A 1 4
# 5: A 2 5
# 6: A 1 6
# 7: B 2 1
# 8: B 2 1
# 9: B 2 1
# 10: B 3 2
# 11: B 3 2
# 12: B 1 3
# 13: C 2 1
# 14: C 3 2
# 15: C 3 2
# 16: C 3 2
# 17: C 1 3
# 18: C 3 4
到目前为止,我尝试了by
个参数的几个不同组合,但运气不佳。我似乎能够得到的最接近的是具有diff
的东西,它可以在发生变化时部分正确显示,但在内部递增。
output <- example
output[, Group := 1:.N, by = paste0(ID, Location, diff(Location))]
output
# ID Location Group
# 1: A 1 1
# 2: A 2 1 # not incrementing/new group
# 3: A 3 1 # not incrementing/new group
# 4: A 1 2
# 5: A 2 1
# 6: A 1 3
# 7: B 2 1
# 8: B 2 2 # incrementing when shouldn't
# 9: B 2 1
# 10: B 3 1
# 11: B 3 1
# 12: B 1 1
# 13: C 2 1
# 14: C 3 1
# 15: C 3 2
# 16: C 3 1
# 17: C 1 1
# 18: C 3 1
在这一点上,我很失落,虽然我确信解决方案正在盯着我。
答案 0 :(得分:3)
您可以按ID
进行分组,然后选择rleid
列的Location
:
example[, Group := rleid(Location), ID]
example
# ID Location Group
# 1: A 1 1
# 2: A 2 2
# 3: A 3 3
# 4: A 1 4
# 5: A 2 5
# 6: A 1 6
# 7: B 2 1
# 8: B 2 1
# 9: B 2 1
#10: B 3 2
#11: B 3 2
#12: B 1 3
#13: C 2 1
#14: C 3 2
#15: C 3 2
#16: C 3 2
#17: C 1 3
#18: C 3 4
all.equal(example, expected_output)
# [1] TRUE