es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Filtrar dataframe según secuencia de filas condicionada en dos columnas.

Tengo este tipo de datos, donde los valores numéricos en la columna Sequ definen una secuencia de filas y el valor de carácter en Q nombra el tipo de secuencia:

df <- data.frame(
  Line = 1:12,
  Speaker = c(NA, "ID01.A", NA, "ID01.B", "ID07.A", NA, "ID33.B", 
              "ID33.A", "ID33.C", NA, "ID77.A", "ID77.C"),
  Utterance = c(NA, "Who did it?", "(1.99)", "Peter did.", "Hello!", NA, "So you're coming?", 
                "erm", "Yes, sure.", "(0.22)", "Good night?", "Yeah, sleep well"),
  Sequ = c(NA,1,1,1, NA,NA, 2,2,2, NA, 3,3),
  Q = c(NA, "q_wh", "", "", NA, NA, "q_decl", "", "", NA, "q_wh", "")
)

Quiero filtrar el dataframe en aquellos valores de Sequ que son numéricos (en lugar de NA) y donde Q == q_wh. Puedo hacer esta tarea utilizando na_if y luego fill:

library(tidyr)
df %>%
  mutate(Q = na_if(Q, "")) %>%
  fill(Q, .direction = "down") %>%
  filter(!is.na(Sequ) & Q == "q_wh")
  Line Speaker        Utterance Sequ    Q
1    2  ID01.A      Who did it?    1 q_wh
2    3    <na>           (1.99)    1 q_wh
3    4  ID01.B       Peter did.    1 q_wh
4   11  ID77.A      Good night?    3 q_wh
5   12  ID77.C Yeah, sleep well    3 q_wh

Pero ¿hay otra forma más directa, sin la vuelta a na_if y fill, de filtrar df?

EDIT:

He encontrado una solución sin fill y na_if:

df %>%
group_by(Sequ) %>%
mutate(Q = Q[!Q==""]) %>%
filter(!is.na(Sequ) & Q == "q_wh")

Tags:  ,

Answer

  1. Avatar for davy.ai

    Sí, hay otra forma de filtrar df sin usar na_if y fill. Puedes agrupar el dataframe por Sequ y luego usar slice para mantener solo las filas donde Q == "q_wh". Aquí está el código:

    library(dplyr)
    
    df %>%
      group_by(Sequ) %>%
      slice(which(Q == "q_wh")) %>%
      filter(!is.na(Sequ))
    

    Este código primero agrupa el dataframe por Sequ. Luego usamos slice para mantener solo las filas donde Q == "q_wh". Esto funciona porque slice mantiene el orden de las filas dentro de cada grupo, por lo que no tenemos que preocuparnos por los valores NA en Sequ. Finalmente, usamos filter para eliminar cualquier valor NA restante en Sequ.

    El resultado de la salida es el mismo que el código original:

    “` r

    A tibble: 5 x 5

    Groups: Sequ [3]

    Line Speaker Utterance Sequ Q

    1 2 ID01.A Who did it? 1 q_wh
    2 3 (1.99) 1 q_wh
    3 4 ID01.B Peter did. 1 q_wh
    4 11 ID77.A Good night? 3 q_wh
    5 12 ID77.C Yeah, sleep well 3 q_wh
    “`

Comments are closed.