Cómo extraer los valores mínimo y máximo basados en condiciones en R.
Tengo un marco de datos con miles de filas y necesito generar los valores mínimo y máximo de secciones de datos que pertenecen al mismo grupo y clase. Lo que necesito es leer el primer valor de inicio, compararlo con el valor anterior en la columna de finalización y, si es menor, saltar a la siguiente fila y así sucesivamente hasta que el valor de inicio sea mayor que el valor final anterior, luego generar el valor mínimo de inicio y el máximo para esa sección. Mis datos ya están ordenados por grupo-clase-inicio-final.
La salida que deseo lograr es:
group class start end
1 1 2 23477018 47909872
2 1 2 48339885 53818713
3 1 3 87274 5329014
4 1 3 6733569 13934484
Cualquier idea sobre cómo lograr esto será muy apreciada.
davy.ai
Para lograr este resultado, podemos utilizar un ciclo para iterar sobre cada fila del marco de datos y comparar los valores de inicio y fin de filas consecutivas dentro del mismo grupo y clase. Si el valor de inicio de la fila actual es menor o igual que el valor final de la fila anterior, actualizamos una variable temporal con el valor final máximo visto hasta ahora. Si el valor de inicio de la fila actual es mayor que el valor final de la fila anterior, producimos el valor de inicio mínimo y el valor final máximo vistos dentro de la sección actual y pasamos a la siguiente sección.
Aquí está el código para implementarlo:
“`{r}
inicializar variables
group_prev <- NA
class_prev <- NA
end_prev <- NA
start_min <- NA
end_max <- NA
función para producir el valor de inicio mínimo y el valor final máximo para la sección
output_section <- function(group, class, start_min, end_max) {
data.frame(group = group, class = class, start = start_min, end = end_max)
}
ciclo sobre las filas del marco de datos
for (i in 1:nrow(df)) {
# extraer los valores de grupo, clase, inicio y fin
group <- df$group[i]
class <- df$class[i]
start <- as.numeric(df$start[i])
end <- as.numeric(df$end[i])
# si es la primera fila o es un grupo/clase diferente, producir la sección si es aplicable y reiniciar las variables
if (i == 1 || group != group_prev || class != class_prev) {
if (!is.na(start_min)) {
print(output_section(group_prev, class_prev, start_min, end_max))
}
start_min <- start
end_max <- end
}
# si es el mismo grupo y clase, comparar inicio y fin con la fila anterior
else {
if (start <= end_prev) {
end_max <- max(end_max, end)
}
else {
print(output_section(group_prev, class_prev, start_min, end_max))
start_min <- start
end_max <- end
}
}
# actualizar los valores anteriores
group_prev <- group
class_prev <- class
end_prev <- end
}
producir la última sección
print(output_section(group_prev, class_prev, start_min, end_max))
group class start end
1 1 2 23477018 47909872
2 1 2 48339885 53818713
3 1 3 87274 5329014
4 1 3 6733569 13934484
“`