studio - superponer graficas en r
Identificar la posiciĆ³n del primer partido en una cadena (7)
Algunas comparaciones:
library(stringi)
library(stringr)
seq <- c("00010010","00001000","10000010","10000000","00010000")
seq2 <- rep(seq, 5e6)
system.time(regexpr("1", seq2))
user system elapsed
4.78 0.03 4.82
system.time(9-nchar(as.numeric(as.character(seq2))))
user system elapsed
34.89 0.18 35.52
system.time(str_locate(pattern =''1'',seq2))
user system elapsed
6.17 0.21 6.53
system.time(stri_locate_first_fixed(seq2, "1")[, 1])
user system elapsed
1.68 0.15 1.84
system.time(nchar(seq2)-round(log10(as.numeric(seq2))))
user system elapsed
7.67 0.09 7.86
system.time(nchar(sub(''1.*'', '''', seq2))+1)
user system elapsed
14.61 0.11 14.93
Tengo una cadena de caracteres ("00010000") y necesito identificar en qué posición vemos el primer "1". (Esto me dice en qué mes está activo un cliente)
Tengo un conjunto de datos que se ve así:
id <- c(1:5)
seq <- c("00010000","00001000","01000000","10000000","00010000")
df <- data.frame(id,seq)
Me gustaría crear un nuevo campo que identifique el first_month_active para cada id.
Puedo hacer esto manualmente con una función Ifelse anidada:
df$first_month_active <-
ifelse(substr(df$seq,1,1)=="1",1,
ifelse(substr(df$seq,2,2)=="1",2,
ifelse(substr(df$seq,3,3)=="1",3,
ifelse(substr(df$seq,4,4)=="1",4,
ifelse(substr(df$seq,5,5)=="1",5,99 )))))
Lo que me da el resultado deseado:
id seq first_position
1 00010000 4
2 00001000 5
3 01000000 2
4 10000000 1
5 00010000 4
Sin embargo, esta no es una solución ideal para mis datos, que contiene 36 meses.
Me gustaría utilizar un bucle con una declaración ifelse, sin embargo, realmente estoy luchando con la sintaxis
for (i in 1:36) {
ifelse(substr(df$seq,0+i,0+i)=="1",0+i,
}
Cualquier idea sería muy apreciada
Lo siguiente podría hacer este trabajo:
library(stringr)
str_locate(pattern =''1'',seq)
O prueba el paquete de stringi
library(stringi)
stri_locate_first_fixed(df$seq, "1")[, 1]
## [1] 4 5 2 1 4
Otra opción usando sub
nchar(sub(''1.*'', '''', seq))+1
#[1] 4 5 2 1 4
Otro, usando log
:
nchar(seq)-round(log10(as.numeric(seq)))
Puedes usar gregexpr
.
> unlist(gregexpr(pattern=1,seq,fixed=T))
[1] 4 5 2 1 4
Salte el loop y el ifelse
:
9 - nchar(as.numeric(seq))
## [1] 4 5 2 1 4
Esto no funcionará igual en su data.frame porque forzó a seq
a factor implícitamente, así que solo haga lo siguiente:
9 - nchar(as.numeric(as.character(df$seq)))
## [1] 4 5 2 1 4
Editar: Solo por diversión, ya que Frank no convirtió su comentario en una respuesta, aquí está la solución strsplit
:
# from original vector
sapply(strsplit(seq, "1"), nchar)[1,] + 1
## [1] 4 5 2 1 4
# from data.frame
sapply(strsplit(as.character(df$seq), "1"), nchar)[1,] + 1
## [1] 4 5 2 1 4