J'ai un dataframe qui ressemble à ceci:
ID value condition newID A 0 0 A A 3 0 A A 0 1 A1 A 7 1 A1 A 5 0 A2 A 5 0 A2 A 5 0 A2 A 7 0 A2 B 6 0 B B 2 1 B1 B 7 0 B2 B 10 1 B3 B 0 0 B4 B 6 0 B4
Je veux changer le nom de l'ID lorsque la condition est remplie et changer le nom de l'ID qui suit également. La condition peut être remplie plusieurs fois par ID, j'aimerais donc la modifier à chaque fois.
Le résultat changerait l'ID d'origine ou ajouterait simplement une nouvelle colonne:
ID value condition A 0 0 A 3 0 A 0 1 A 7 1 A 5 0 A 5 0 A 5 0 A 7 0 B 6 0 B 2 1 B 7 0 B 10 1 B 0 0 B 6 0
4 Réponses :
Une option après le regroupement par 'ID', créez l'index avec rleid (à partir de data.table ) et changez-le en collez le 'ID' basé sur la condition avec case_when
df1 <- structure(list(ID = c("A", "A", "A", "A", "A", "A", "A", "A",
"B", "B", "B", "B", "B", "B"), value = c(0L, 3L, 0L, 7L, 5L,
5L, 5L, 7L, 6L, 2L, 7L, 10L, 0L, 6L), condition = c(0L, 0L, 1L,
1L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 0L, 0L)), class = "data.frame",
row.names = c(NA, -14L))
library(dplyr)
library(data.table)
df1 %>%
group_by(ID) %>%
mutate(newID = rleid(condition)-1,
newID = case_when(newID == 0 ~ first(ID), TRUE ~ paste0(first(ID), newID)))
# A tibble: 14 x 4
# Groups: ID [2]
# ID value condition newID
# <chr> <int> <int> <chr>
# 1 A 0 0 A
# 2 A 3 0 A
# 3 A 0 1 A1
# 4 A 7 1 A1
# 5 A 5 0 A2
# 6 A 5 0 A2
# 7 A 5 0 A2
# 8 A 7 0 A2
# 9 B 6 0 B
#10 B 2 1 B1
#11 B 7 0 B2
#12 B 10 1 B3
#13 B 0 0 B4
#14 B 6 0 B4
Pourrait également faire:
# A tibble: 14 x 4 # Groups: ID [2] ID value condition newID <chr> <int> <int> <chr> 1 A 0 0 A 2 A 3 0 A 3 A 0 1 A1 4 A 7 1 A1 5 A 5 0 A2 6 A 5 0 A2 7 A 5 0 A2 8 A 7 0 A2 9 B 6 0 B 10 B 2 1 B1 11 B 7 0 B2 12 B 10 1 B3 13 B 0 0 B4 14 B 6 0 B4
Sortie:
library(dplyr)
df %>%
group_by(ID) %>%
mutate(newID = cumsum(c(0, (condition != lag(condition))[-1])),
newID = ifelse(newID != 0, paste0(ID, newID), ID))
Même idée que @akrun mais en utilisant uniquement data.table
library(data.table)
setDT(df)
df[, newID := paste0(ID, gsub('^0$', '', rleid(condition) - 1)), ID]
df
# ID value condition newID
# 1: A 0 0 A
# 2: A 3 0 A
# 3: A 0 1 A1
# 4: A 7 1 A1
# 5: A 5 0 A2
# 6: A 5 0 A2
# 7: A 5 0 A2
# 8: A 7 0 A2
# 9: B 6 0 B
# 10: B 2 1 B1
# 11: B 7 0 B2
# 12: B 10 1 B3
# 13: B 0 0 B4
# 14: B 6 0 B4
Si je comprends bien, l'OP souhaite créer des sous-groupes dans chaque ID pour chaque séquence contiguë de condition .
Malheureusement, l'OP a demandé de nommer le sous-groupes d'une manière spéciale qui rend les solutions trop compliquées. À la demande de OP, les sous-groupes doivent être nommés, par exemple, A, A1, A2 ce qui signifie que la numérotation des sous-groupes et le nom du sous-groupe sont désactivés de un, par exemple, le deuxième sous-groupe est nommé A1 , le troisième A2 , etc.
Dans le cas où un schéma de dénomination plus simplifié serait acceptable, nous pouvons directement bénéficier du préfixe paramètre de la fonction rleid () . Ensuite, le premier sous-groupe du groupe A sera nommé A1 , le deuxième A2 , etc.
library(data.table)
df <- fread("ID value condition
A 0 0
A 3 0
A 0 1
A 7 1
A 5 0
A 5 0
A 5 0
A 7 0
B 6 0
B 2 1
B 7 0
B 10 1
B 0 0
B 6 0")
ID value condition newID 1: A 0 0 A1 2: A 3 0 A1 3: A 0 1 A2 4: A 7 1 A2 5: A 5 0 A3 6: A 5 0 A3 7: A 5 0 A3 8: A 7 0 A3 9: B 6 0 B1 10: B 2 1 B2 11: B 7 0 B3 12: B 10 1 B4 13: B 0 0 B5 14: B 6 0 B5
library(data.table) setDT(df)[, newID := rleid(condition, prefix = ID), ID][]
# A tibble: 14 x 4 # Groups: ID [2] ID value condition newID <chr> <int> <int> <chr> 1 A 0 0 A1 2 A 3 0 A1 3 A 0 1 A2 4 A 7 1 A2 5 A 5 0 A3 6 A 5 0 A3 7 A 5 0 A3 8 A 7 0 A3 9 B 6 0 B1 10 B 2 1 B2 11 B 7 0 B3 12 B 10 1 B4 13 B 0 0 B5 14 B 6 0 B5
library(dplyr) df %>% group_by(ID) %>% mutate(newID = data.table::rleid(condition, prefix = first(ID)))