Filtro agrupado fila por mayor ocurrencia de cadena con dplyr

Estoy trabajando en la colapsación de un conjunto de datos transcripcionómicos de nivel de transcripción a gen para un análisis aguas abajo. Dentro de este conjunto de datos, cada fila tiene un identificador de genes único (qry_gene_id) y cada uno qry_gene_id puede tener múltiples qry_transcript_ids. Me gustaría filtrar el conjunto de datos para seleccionar el qry_transcript_id de cada uno qry_gene_id que tiene el mayor número de go_id (GO:XXXXXXX). El go_id columna es una lista de go_ids separated by ",".

Aquí hay un subconjunto mis datos:

structure(list(qry_transcript_id = c("TU22", "TU20", "TU27", 
"TU29", "TU25", "TU26", "TU28", "TU31", "TU24", "TU30"), go_id = c(NA, 
NA, "GO:0004672,GO:0005515,GO:0005524,GO:0006468", "GO:0005003,GO:0005515,GO:0005524,GO:0005887,GO:0006468,GO:0007169", 
"GO:0005003,GO:0005515,GO:0005524,GO:0005887,GO:0006468,GO:0007169", 
"GO:0005003,GO:0005515,GO:0005524,GO:0005887,GO:0006468,GO:0007169", 
"GO:0005003,GO:0005515,GO:0005524,GO:0005887,GO:0006468,GO:0007169", 
"GO:0005003,GO:0005515,GO:0005524,GO:0005887,GO:0006468,GO:0007169", 
"GO:0005003,GO:0005515,GO:0005524,GO:0005887,GO:0006468,GO:0007169", 
"GO:0005003,GO:0005515,GO:0005524,GO:0005887,GO:0006468,GO:0007169"
), ref_gene_id = c("LOC108906571", "LOC108906589", "LOC108906588", 
"LOC108906588", "LOC108906588", "LOC108906588", "LOC108906588", 
"LOC108906588", "LOC108906588", "LOC108906588"), qry_gene_id = c("G10", 
"G9", "G12", "G12", "G12", "G12", "G12", "G12", "G12", "G12"), 
    ref_gene_name = c("uncharacterized LOC108906571", "uncharacterized LOC108906589", 
    "ephrin type-B receptor 1-B", "ephrin type-B receptor 1-B", 
    "ephrin type-B receptor 1-B", "ephrin type-B receptor 1-B", 
    "ephrin type-B receptor 1-B", "ephrin type-B receptor 1-B", 
    "ephrin type-B receptor 1-B", "ephrin type-B receptor 1-B"
    ), gene_annotation = c("refseq", "refseq", "refseq", "refseq", 
    "refseq", "refseq", "refseq", "refseq", "refseq", "refseq"
    ), ref_transcript_id = c("XM_018709871.1", "XM_018709894.2", 
    "XM_018709891.1", "XM_018709891.1", "XM_018709891.1", "XM_018709891.1", 
    "XM_018709891.1", "XM_018709891.1", "XM_018709891.1", "XM_018709891.1"
    ), ref_transcript_name = c("uncharacterized LOC108906571", 
    "uncharacterized LOC108906589", "ephrin type-B receptor 1-B, transcript variant X2", 
    "ephrin type-B receptor 1-B, transcript variant X2", "ephrin type-B receptor 1-B, transcript variant X2", 
    "ephrin type-B receptor 1-B, transcript variant X2", "ephrin type-B receptor 1-B, transcript variant X2", 
    "ephrin type-B receptor 1-B, transcript variant X2", "ephrin type-B receptor 1-B, transcript variant X2", 
    "ephrin type-B receptor 1-B, transcript variant X2"), class_code = c("i", 
    "k", "j", "j", "=", "j", "j", "j", "j", "j")), row.names = 21:30, class = "data.frame")

Como puedes ver qry_gene_id = G12, la primera transcripción falta un par de ids GO. Quiero asegurarme de que mi filtro seleccione una transcripción que tiene el cumplido completo de los ids GO.

Sin embargo, estoy atrapado en cómo filtrar esto apropiadamente. Aquí es donde estoy.

test_data <- test_data %>% group_by(qry_gene_id) %>% filter()

Me parece lógico que filtrar por cualquiera 1) la longitud total de esa cadena (que creo que debería capturar la lista más larga de los términos GO) o 2) contando ocurrencias de una cadena (por ejemplo, "GO") y seleccionando las que tienen el mayor recuento de "GO". Básicamente quiero terminar sin dejar ninguno de los términos GO asociados con cada gen.

Pregunta hecha hace 3 años, 4 meses, 29 días - Por techtrailblazer8d2c


3 Respuestas:

  • He aquí un acercamiento para mantener las filas con el conteo más alto de "GO" en cada grupo:

    library(dplyr)
    library(stringr)
    test_data %>% 
      mutate(go_count = str_count(go_id, "GO")) %>%
      group_by(qry_gene_id) %>% 
      slice_max(go_count)
    

    See ?slice_max en caso de que quieras afinar esto, por ejemplo, ajustar lo que sucede cuando hay vínculos. El predeterminado mantendrá todas las filas atadas para las más ocurrencias de "GO" dentro de un grupo.

    También podrías usar algo como filter(which.max(nchar(go_id))), manteniendo el número máximo de caracteres.

    Respondida el Dec 17, 2020 a las 15:25 - por syntaxsavvy

    Votos positivos: 0 | Votos negativos: 0

  • Para lograr lo que deseas, puedes usar la función str_count de stringr para contar la cantidad de ocurrencias de "GO" en la columna go_id. Luego, puedes filtrar las filas dentro de cada grupo de qry_gene_id seleccionando aquellas que tengan el mayor número de ocurrencias de "GO" utilizando la función which.max.

    Aquí te muestro cómo podrías hacerlo con dplyr:

    R
    library(dplyr)
    library(stringr)
    
    filtered_data <- test_data %>%
      group_by(qry_gene_id) %>%
      filter(row_number() == which.max(str_count(go_id, "GO")))
    

    En este código, str_count(go_id, "GO") cuenta cuántas veces aparece "GO" en cada fila de go_id. Luego, which.max devuelve el índice de la fila en cada grupo que tiene el máximo número de ocurrencias de "GO". Finalmente, filter(row_number() == ...) selecciona solo las filas que corresponden a ese máximo.

    Espero que esta solución te sea útil para filtrar tus datos de acuerdo a tu requerimiento. ¡Déjame saber si tienes alguna otra pregunta!

    Respondida el Dec 18, 2020 a las 15:25 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Aquí hay una solución utilizando la función count de dplyr para contar el número de ocurrencias de cada go_id y luego seleccionar el qry_transcript_id con el mayor recuento:

    
    library(dplyr)
    
    test_data %>%
      

    Cuenta el número de ocurrencias de cada go_id

    group_by(qry_transcript_id) %>% summarize(go_id_count = n_distinct(go_id)) %>%

    Selecciona el qry_transcript_id con el mayor recuento de go_id

    arrange(desc(go_id_count)) %>% slice(1)

    Respondida el Dec 18, 2020 a las 15:35 - por Gemini

    Votos positivos: 0 | Votos negativos: 0