Selezione delle righe del frame di dati in base alla corrispondenza parziale della stringa in una colonna


96

Voglio selezionare le righe da un frame di dati in base alla corrispondenza parziale di una stringa in una colonna, ad esempio la colonna "x" contiene la stringa "hsa". Usando sqldf- se avesse una likesintassi - farei qualcosa del tipo:

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

Sfortunatamente, sqldfnon supporta questa sintassi.

O allo stesso modo:

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

Che ovviamente non funziona.

Qualcuno può aiutarmi con questo?


6
Puoi pubblicare alcune righe dei tuoi dati, preferibilmente usando qualcosa di simile dput(head(conservedData)).
A5C1D2H2I1M1N2O1R2T1

Risposte:


147

Ho notato che hai menzionato una funzione %like%nel tuo approccio attuale. Non so se sia un riferimento a %like%"data.table", ma se lo è, puoi sicuramente usarlo come segue.

Nota che l'oggetto non deve essere a data.table(ma ricorda anche che gli approcci di sottoinsiemi per data.frames e data.tables non sono identici):

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

Se questo è ciò che avevi, forse hai appena confuso le posizioni di riga e colonna per il sottoinsieme dei dati.


Se non vuoi caricare un pacchetto, puoi provare a usare grep()per cercare la stringa che stai cercando. Ecco un esempio con il mtcarsset di dati, in cui corrispondiamo a tutte le righe in cui i nomi delle righe includono "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

E, un altro esempio, utilizzando il irisset di dati cercando la stringa 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

Per il tuo problema prova:

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

+1: nota anche che grepsupporta le espressioni regolari quindi potresti voler usare grep per ^hsa-.
nico

3
@nico: infatti grepproviene dal comando ed g / re / p (global / regular expression / print), e rivela il suo vero potere solo al maestro delle espressioni regolari-fu ;-): en.wikipedia.org/ wiki /
Grep

1
Il suggerimento % like% è fantastico! Consiglio di metterlo in cima alla tua risposta.
Aren Cambre

@ArenCambre, fatto. Forse mi aiuterà a ottenere altri 11 voti in modo da poter ottenere un nuovo cappello prima della fine dell'anno :-)
A5C1D2H2I1M1N2O1R2T1

@ A5C1D2H2I1M1N2O1R2T1 Ottima risposta! C'è un modo per utilizzare% like% per cercare due stringhe che ricorrono insieme (come in "pet" e "pip" che si verificano in una riga di un dataframe come "peter piper")?
nigus21

60

Prova str_detect()dal pacchetto stringr , che rileva la presenza o l'assenza di un pattern in una stringa.

Ecco un approccio che incorpora anche il %>%pipe e filter()dal pacchetto 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
...

Questo filtra il set di dati di CO2 campione (fornito con R) per le righe in cui la variabile di trattamento contiene la sottostringa "non". Puoi regolare se str_detecttrova corrispondenze fisse o utilizza una regex - consulta la documentazione per il pacchetto stringr.


Puoi anche utilizzare la funzione trc_detect in questo modomyDataFrame[str_detect(myDataFrame$key, myKeyPattern),]
Bemipefe

20

LIKE dovrebbe funzionare in 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 è il migliore per l'elenco. Tuttavia, non può eliminare righe.
Suat Atan PhD

1
Perché viene caricato un pacchetto R require()qui
rgalbo

Perché non è una libreria R standard e devi installarla manualmente e quindi caricarla usando la requirefunzione.
bartektartanus
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.