Sélection de lignes de bloc de données en fonction d'une correspondance de chaîne partielle dans une colonne


97

Je veux sélectionner des lignes à partir d'un bloc de données basé sur une correspondance partielle d'une chaîne dans une colonne, par exemple la colonne «x» contient la chaîne «hsa». En utilisant sqldf- s'il avait une likesyntaxe - je ferais quelque chose comme:

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

Malheureusement, sqldfne prend pas en charge cette syntaxe.

Ou de même:

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

Ce qui, bien sûr, ne fonctionne pas.

Quelqu'un peut-il m'aider s'il vous plaît?


6
Pouvez-vous publier quelques lignes de vos données, de préférence en utilisant quelque chose comme dput(head(conservedData)).
A5C1D2H2I1M1N2O1R2T1

Réponses:


149

Je remarque que vous mentionnez une fonction %like%dans votre approche actuelle. Je ne sais pas si c'est une référence au %like%"data.table" de from, mais si c'est le cas, vous pouvez certainement l'utiliser comme suit.

Notez que l'objet n'a pas besoin d'être a data.table(mais rappelez-vous également que les approches de sous-ensembles pour data.frames et data.tables ne sont pas identiques):

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

Si c'est ce que vous aviez, alors peut-être que vous aviez juste mélangé les positions de ligne et de colonne pour les données de sous-ensemble.


Si vous ne souhaitez pas charger un package, vous pouvez essayer d'utiliser grep()pour rechercher la chaîne que vous correspondez. Voici un exemple avec l' mtcarsensemble de données, où nous faisons correspondre toutes les lignes dont les noms de ligne incluent "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

Et, un autre exemple, en utilisant l' irisensemble de données recherchant la chaîne 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

Pour votre problème, essayez:

selectedRows <- conservedData[grep("hsa-", conservedData$miRNA), ]

+1: notez également que grepprend en charge les expressions régulières, vous pouvez donc utiliser un grep à la ^hsa-place.
nico

3
@nico: en fait, grepvient de la commande ed g / re / p (global / expression régulière / impression), et il ne révèle sa vraie puissance qu'au maître de l'expression régulière-fu ;-): en.wikipedia.org/ wiki / Grep
Stephan Kolassa

1
La suggestion % like% est géniale! Je recommande de le mettre en haut de votre réponse.
Aren Cambre

@ArenCambre, c'est fait. Peut-être que cela m'aidera à obtenir 11 votes
supplémentaires

@ A5C1D2H2I1M1N2O1R2T1 Excellente réponse! Existe-t-il un moyen d'utiliser% like% pour rechercher deux chaînes qui se produisent ensemble (comme dans "pet" et "pip" apparaissant dans une ligne d'un dataframe comme "peter piper")?
nigus21 le

61

Essayez à str_detect()partir du package stringr , qui détecte la présence ou l'absence d'un modèle dans une chaîne.

Voici une approche qui intègre également le %>%pipe et filter()du package 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
...

Cela filtre le jeu de données échantillon CO2 (fourni avec R) pour les lignes où la variable Traitement contient la sous-chaîne "non". Vous pouvez ajuster si str_detecttrouve des correspondances fixes ou utilise une expression régulière - voir la documentation du package stringr.


Vous pouvez également utiliser la fonction trc_detect comme cecimyDataFrame[str_detect(myDataFrame$key, myKeyPattern),]
Bemipefe

20

LIKE devrait fonctionner dans 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

SQLDF est le meilleur pour la liste. Cependant, il ne peut pas supprimer des lignes.
Suat Atan PhD

1
Pourquoi un paquet R est chargé require()ici
rgalbo

Parce qu'il ne s'agit pas d'une bibliothèque R standard et que vous devez l'installer manuellement, puis charger à l'aide de la requirefonction.
bartektartanus
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.