Alice
Alice

Reputation: 54

How to repeat the same value according to factor levels?

I would like to create an ID for each exercise and name them relative to the number of the exercise. An output like that :

# A tibble: 13 x 2
   Cmpt       ID     
   <chr>      <chr>  
 1 Exercice 1 ID_0001
 2 Exercice 1 ID_0001
 3 Exercice 1 ID_0001
 4 Exercice 1 ID_0001
 5 Exercice 1 ID_0001
 6 Exercice 2 ID_0002
 7 Exercice 2 ID_0002
 8 Exercice 2 ID_0002
 9 Exercice 2 ID_0002
10 Exercice 2 ID_0002
11 Exercice 3 ID_0003
12 Exercice 3 ID_0003
13 Exercice 3 ID_0003

I tried :

complement<-c("000","00","0","")
valeur<-1
rep(paste(complement[nchar(valeur)],valeur,sep=""), each = length(data[data$Exercice=="Exercice 1",]))

This gave me :

[1] "0001" "0001" "0001" "0001" "0001"

That's what I want, but I would like this for every levels' factor which are "Exercice 1, Exercice 2, Exercice 3", and then detect when the levels change automatically. Probably with a for loop ?

Thank you!

Upvotes: 0

Views: 52

Answers (1)

JBGruber
JBGruber

Reputation: 12410

Here is a dplyr solution showing the individual steps:

library(dplyr)
df %>% 
  mutate(ID2 = gsub("[^[:digit:]]", "", Cmpt)) %>% 
  mutate(ID2 = as.integer(ID2)) %>% 
  mutate(ID2 = sprintf("ID_%04i", ID2))
#>          Cmpt      ID     ID2
#> 1  Exercice 1 ID_0001 ID_0001
#> 2  Exercice 1 ID_0001 ID_0001
#> 3  Exercice 1 ID_0001 ID_0001
#> 4  Exercice 1 ID_0001 ID_0001
#> 5  Exercice 1 ID_0001 ID_0001
#> 6  Exercice 2 ID_0002 ID_0002
#> 7  Exercice 2 ID_0002 ID_0002
#> 8  Exercice 2 ID_0002 ID_0002
#> 9  Exercice 2 ID_0002 ID_0002
#> 10 Exercice 2 ID_0002 ID_0002
#> 11 Exercice 3 ID_0003 ID_0003
#> 12 Exercice 3 ID_0003 ID_0003
#> 13 Exercice 3 ID_0003 ID_0003

Or as a one-liner in base R:

sprintf("ID_%04i", as.integer(gsub("[^[:digit:]]", "", df$Cmpt)))

The crucial part here is sprintf, which can do some advanced formatting. In this case %04i means to take the provided integer and output it with a width of at least 4, no matter how long it originally is:

sprintf("ID_%04i", 352)
#> [1] "ID_0352"

sprintf("ID_%04i", 99999)
#> [1] "ID_99999"

Upvotes: 2

Related Questions