Agregue una columna que itere/ cuente cada vez que una secuencia se reinicia.
Tengo un dataframe con una columna que aumenta con cada fila y se reinicia periódicamente (aunque no regularmente) de nuevo a 1. Me gustaría realizar un seguimiento / contar estos reinicios en una columna separada. Este ejemplo de bucle hace exactamente lo que quiero, pero es increíblemente lento cuando se aplica a conjuntos de datos grandes. ¿Existe una mejor / más rápida / más R manera de realizar esta misma operación?
ColA<-seq(1,20)
ColB<-rep(seq(1,5),4)
DF<-data.frame(ColA, ColB)
DF$ColC<-NA
DF[1,'ColC']<-1
#Eliminando la línea 15 y cambiando la línea 5 a 1.1 por comentarios en la respuesta
DF<-DF[-15,]
DF[5,2]<-0.1
for(i in seq(1,nrow(DF)-1)){
print(i)
MyRow<-DF[i+1,]
if(MyRow$ColB < DF[i,'ColB']){
DF[i+1,"ColC"]<-DF[i,"ColC"] +1
}else{
DF[i+1,"ColC"]<-DF[i,"ColC"]
}
}
davy.ai
En lugar de usar un ciclo for, puedes utilizar el paquete
dplyr
de R, que puede ser más eficiente para conjuntos de datos grandes. Aquí tienes un ejemplo de cómo puedes usardplyr
para agregar una nueva columnaColC_reset
que cuenta el número de reinicios enColB
:Lo que hace este código:
–
mutate()
agrega una nueva columnaColC_reset
aDF
–
ifelse()
verifica si el valor deColB
de cada fila es menor que el valor deColB
de la fila anterior (usandolag()
, que desplaza un vector o columna hacia abajo en una posición), lo que indica un reinicio. Si es así, entonces se asignacumsum(!is.na(ColC)) + 1
a la nueva columnaColC_reset
, lo que suma 1 al recuento acumulativo de valores no-NAs enColC
y marca el inicio de un nuevo recuento de reinicios. Si no se cumple la condición deifelse()
, entoncescumsum(!is.na(ColC))
se asigna aColC_reset
, lo que continúa el recuento actual de reinicios.–
na.omit()
elimina cualquier fila que tenga NA en la columnaColC
(que se crearon en el código original si el valor deColB
de la primera fila fue menor que cualquier otro valor deColB
).Esto debería darte el mismo resultado que el ciclo for, pero con mejor rendimiento para conjuntos de datos grandes.