Filtra data.frame filas por una condición lógica
Pregunta
Quiero filtrar filas de una data.frame
basado en una condición lógica. Supongamos que tengo trama de datos como
expr_value cell_type
1 5.345618 bj fibroblast
2 5.195871 bj fibroblast
3 5.247274 bj fibroblast
4 5.929771 hesc
5 5.873096 hesc
6 5.665857 hesc
7 6.791656 hips
8 7.133673 hips
9 7.574058 hips
10 7.208041 hips
11 7.402100 hips
12 7.167792 hips
13 7.156971 hips
14 7.197543 hips
15 7.035404 hips
16 7.269474 hips
17 6.715059 hips
18 7.434339 hips
19 6.997586 hips
20 7.619770 hips
21 7.490749 hips
Lo que quiero es conseguir una nueva trama de datos, que tiene el mismo aspecto, pero sólo tiene los datos para un cell_type. P.ej. de subconjunto / seleccione filas que contiene el tipo de célula "HESC":
expr_value cell_type
1 5.929771 hesc
2 5.873096 hesc
3 5.665857 hesc
O cualquiera de los tipos de células "de fibroblastos BJ" o "HESC":
expr_value cell_type
1 5.345618 bj fibroblast
2 5.195871 bj fibroblast
3 5.247274 bj fibroblast
4 5.929771 hesc
5 5.873096 hesc
6 5.665857 hesc
¿Hay alguna forma fácil de hacer esto?
He intentado:
expr[expr[2] == 'hesc']
# [1] "5.929771" "5.873096" "5.665857" "hesc" "hesc" "hesc"
si la trama de datos original se llama "expr", pero da los resultados en un formato incorrecto como se puede ver.
Solución
Para seleccionar filas según uno 'cell_type' (por ejemplo 'HESC'), el uso ==
:
expr[expr$cell_type == "hesc", ]
Para seleccionar filas de acuerdo con dos o más diferentes 'cell_type', (por ejemplo, ya sea 'HESC' o 'bj fibroblastos'), el uso %in%
:
expr[expr$cell_type %in% c("hesc", "bj fibroblast"), ]
Otros consejos
Uso subset
(para uso interactivo)
subset(expr, cell_type == "hesc")
subset(expr, cell_type %in% c("bj fibroblast", "hesc"))
o mejor dplyr::filter()
filter(expr, cell_type %in% c("bj fibroblast", "hesc"))
La razón expr[expr[2] == 'hesc']
que no funciona es que para una trama de datos, x[y]
selecciona columnas, no las filas. Si desea seleccionar filas, cambiar a la vez x[y,]
sintaxis:
> expr[expr[2] == 'hesc',]
expr_value cell_type
4 5.929771 hesc
5 5.873096 hesc
6 5.665857 hesc
Se puede usar el paquete dplyr
:
library(dplyr)
filter(expr, cell_type == "hesc")
filter(expr, cell_type == "hesc" | cell_type == "bj fibroblast")
A veces, la columna que desea filtrar puede aparecer en una posición diferente que el índice de la columna 2 o tener un nombre de variable.
En este caso, sólo tiene que remitir el nombre de la columna que desea filtrar como:
columnNameToFilter = "cell_type"
expr[expr[[columnNameToFilter]] == "hesc", ]
Yo estaba trabajando en una trama de datos y que no tiene suerte con las respuestas proporcionadas, siempre devuelve 0 filas, por lo que se encontró y se utiliza Grepl:
df = df[grepl("downlink",df$Transmit.direction),]
Lo que básicamente recorta mi trama de datos que sólo las filas que contenían "enlace descendente" en la columna de la dirección de transmisión. PD Si alguien puede adivinar por qué no estoy viendo el comportamiento esperado, por favor dejar un comentario.
En concreto a la pregunta original:
expr[grepl("hesc",expr$cell_type),]
expr[grepl("bj fibroblast|hesc",expr$cell_type),]
Nadie parece haber incluido el que funcionan. También puede resultar útil para el filtrado.
expr[which(expr$cell == 'hesc'),]
Esto también se encargará de AN y soltarlos de la trama de datos resultante.
La ejecución de este 9840 en un 24 por trama de datos de 50.000 veces, parece que el método que tiene un tiempo de ejecución de 60% más rápido que el método% en%.
podemos utilizar la biblioteca data.table
library(data.table)
expr <- data.table(expr)
expr[cell_type == "hesc"]
expr[cell_type %in% c("hesc","fibroblast")]
o filtro utilizando operador %like%
para coincidencia de patrones
expr[cell_type %like% "hesc"|cell_type %like% "fibroblast"]