Seleccionar filas de marcos de datos en función de la coincidencia parcial de cadenas en una columna

97

Quiero seleccionar filas de un marco de datos basado en la coincidencia parcial de una cadena en una columna, por ejemplo, la columna 'x' contiene la cadena "hsa". Usando sqldf, si tuviera una likesintaxis, haría algo como:

select * from <> where x like 'hsa'.

Desafortunadamente, sqldfno es compatible con esa sintaxis.

O similar:

selectedRows <- df[ , df$x %like% "hsa-"]

Lo cual, por supuesto, no funciona.

¿Puede alguien ayudarme con esto?

Asda
fuente
6
¿Puede publicar algunas líneas de sus datos, preferiblemente usando algo como dput(head(conservedData)).
A5C1D2H2I1M1N2O1R2T1

Respuestas:

149

Noto que menciona una función %like%en su enfoque actual. No sé si eso es una referencia a %like%from "data.table", pero si lo es, definitivamente puede usarlo de la siguiente manera.

Tenga en cuenta que el objeto no tiene que ser a data.table(pero también recuerde que los enfoques de subconjuntos para data.framesy data.tables no son idénticos):

library(data.table)
mtcars[rownames(mtcars) %like% "Merc", ]
iris[iris$Species %like% "osa", ]

Si eso es lo que tenía, entonces quizás acababa de mezclar las posiciones de filas y columnas para subconjuntos de datos.


Si no desea cargar un paquete, puede intentar usarlo grep()para buscar la cadena que está haciendo coincidir. Aquí hay un ejemplo con el mtcarsconjunto de datos, donde estamos haciendo coincidir todas las filas donde los nombres de las filas incluyen "Merc":

mtcars[grep("Merc", rownames(mtcars)), ]
             mpg cyl  disp  hp drat   wt qsec vs am gear carb
# Merc 240D   24.4   4 146.7  62 3.69 3.19 20.0  1  0    4    2
# Merc 230    22.8   4 140.8  95 3.92 3.15 22.9  1  0    4    2
# Merc 280    19.2   6 167.6 123 3.92 3.44 18.3  1  0    4    4
# Merc 280C   17.8   6 167.6 123 3.92 3.44 18.9  1  0    4    4
# Merc 450SE  16.4   8 275.8 180 3.07 4.07 17.4  0  0    3    3
# Merc 450SL  17.3   8 275.8 180 3.07 3.73 17.6  0  0    3    3
# Merc 450SLC 15.2   8 275.8 180 3.07 3.78 18.0  0  0    3    3

Y, otro ejemplo, usando el irisconjunto de datos buscando la cadena osa:

irisSubset <- iris[grep("osa", iris$Species), ]
head(irisSubset)
#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1          5.1         3.5          1.4         0.2  setosa
# 2          4.9         3.0          1.4         0.2  setosa
# 3          4.7         3.2          1.3         0.2  setosa
# 4          4.6         3.1          1.5         0.2  setosa
# 5          5.0         3.6          1.4         0.2  setosa
# 6          5.4         3.9          1.7         0.4  setosa

Para su problema intente:

selectedRows <- conservedData[grep("hsa-", conservedData$miRNA), ]
A5C1D2H2I1M1N2O1R2T1
fuente
+1: también tenga en cuenta que grepadmite expresiones regulares, por lo que es posible que desee grep en su ^hsa-lugar.
nico
3
@nico: de hecho, grepproviene del comando ed g / re / p (global / regular expression / print), y revela su poder real solo al maestro de la expresión regular-fu ;-): en.wikipedia.org/ wiki / Grep
Stephan Kolassa
1
¡La sugerencia % like% es genial! Recomiendo ponerlo al principio de su respuesta.
Aren Cambre
@ArenCambre, hecho. Tal vez me ayude a obtener otros 11 votos para poder obtener un sombrero nuevo antes de fin de año :-)
A5C1D2H2I1M1N2O1R2T1
@ A5C1D2H2I1M1N2O1R2T1 ¡Gran respuesta! ¿Hay alguna manera de usar% like% para buscar dos cadenas que ocurren juntas (como en "pet" y "pip" que ocurren en una fila de un marco de datos como "peter piper")?
nigus21
62

Pruebe str_detect()con el paquete stringr , que detecta la presencia o ausencia de un patrón en una cadena.

Aquí hay un enfoque que también incorpora la %>%tubería y filter()del paquete dplyr :

library(stringr)
library(dplyr)

CO2 %>%
  filter(str_detect(Treatment, "non"))

   Plant        Type  Treatment conc uptake
1    Qn1      Quebec nonchilled   95   16.0
2    Qn1      Quebec nonchilled  175   30.4
3    Qn1      Quebec nonchilled  250   34.8
4    Qn1      Quebec nonchilled  350   37.2
5    Qn1      Quebec nonchilled  500   35.3
...

Esto filtra el conjunto de datos de muestra de CO2 (que viene con R) para las filas donde la variable Tratamiento contiene la subcadena "no". Puede ajustar si str_detectencuentra coincidencias fijas o usa una expresión regular; consulte la documentación del paquete stringr.

Sam Firke
fuente
También puede usar la función trc_detect de esta maneramyDataFrame[str_detect(myDataFrame$key, myKeyPattern),]
Bemipefe
20

LIKE debería funcionar en sqlite:

require(sqldf)
df <- data.frame(name = c('bob','robert','peter'),id=c(1,2,3))
sqldf("select * from df where name LIKE '%er%'")
    name id
1 robert  2
2  peter  3
usuario1609452
fuente
SQLDF es mejor para la lista. Sin embargo, no puede eliminar filas.
Suat Atan PhD
1
¿Por qué se carga un paquete R require()aquí?
rgalbo
Porque no es una biblioteca R estándar y debe instalarla manualmente y luego cargarla usando la requirefunción.
bartektartanus