Используя пакет data.table , мы можем сохранить исходную сортировку (рекомендуется):
library(data.table)
setDT(df1)[,new_col:=.GRP-1, by = c("A", "B","C")]
#if you want the column as factor (one-liner, no need for previous line)
setDT(df1)[,new_col:=.GRP-1, by = c("A", "B","C")][,new_col:=as.factor(new_col)]
Используя dplyr , мы можем сделать что-то вроде ниже:
( решение Руи реализовано в dplyr
с минимальной модификацией с учетом возможности дублирования строк):
Это также сохраняет сортировку;
df1 %>% mutate(mtemp=paste0(A,B,C)) %>%
mutate(new_col = as.integer(factor(mtemp, levels = unique(.$mtemp)))-1) %>%
select(-mtemp)
Мы можем использовать фиктивную переменную для обозначения данных:
df1 %>% mutate(mtemp = paste0(A,B,C)) %>%
group_by(mtemp) %>% arrange(mtemp) %>% ungroup() %>%
mutate(new_col = c(0,cumsum(lead(mtemp)[-n()] != lag(mtemp)[-1]))) %>% select(-mtemp)
# # A tibble: 8 x 5
# A B C newCol new_col
# <dbl> <dbl> <dbl> <int> <dbl>
# 1 0 0 0 0 0
# 2 0 0 0 0 0
# 3 0 0 1 3 1
# 4 0 1 0 2 2
# 5 0 1 1 5 3
# 6 1 0 0 1 4
# 7 1 1 0 4 5
# 8 1 1 1 6 6
или в отношении этой нити :
df1 %>%
mutate(group_id = group_indices(., paste0(A,B,C)))
Объяснение dplyr
решений:
Первое решение создает фиктивную переменную, вставляя все три требуемые переменные вместе;на следующем шаге каждая группа этого фиктивного var получает уникальный идентификатор (сравните newCol
с new_col
).В основном, если mtemp
изменяется между любыми двумя строками, мы получаем True
(его числовое значение 1
) как ответ нашего сравнения (lead(mtemp)...
), а затем cumsum
добавляет его к предыдущему сгенерированному идентификатору, который в конечном итогеприводит к различным идентификаторам для разных mtemp
(комбинация A
, B
и C
).Это решение основано на расположении фиктивной переменной и поэтому не учитывает требования сортировки.
Для другого решения просто прочитайте ?group_indices
.
Данные:
df1 <- structure(list(A = c(0, 1, 0, 0, 0, 1, 0, 1), B = c(0, 0, 0,
1, 0, 1, 1, 1), C = c(0, 0, 0, 0, 1, 0, 1, 1), newCol = c(0L,
1L, 0L, 2L, 3L, 4L, 5L, 6L)), class = "data.frame", row.names = c(NA,
-8L))