Auswählen von Datenrahmenzeilen basierend auf einer teilweisen Zeichenfolgenübereinstimmung in einer Spalte


96

Ich möchte Zeilen aus einem Datenrahmen basierend auf der teilweisen Übereinstimmung einer Zeichenfolge in einer Spalte auswählen, z. B. enthält die Spalte 'x' die Zeichenfolge "hsa". Mit sqldf- wenn es eine likeSyntax hätte - würde ich etwas tun wie:

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

sqldfUnterstützt diese Syntax leider nicht.

Oder ähnlich:

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

Was natürlich nicht funktioniert.

Kann mir bitte jemand dabei helfen?


6
Können Sie ein paar Zeilen Ihrer Daten posten, vorzugsweise mit etwas wie dput(head(conservedData)).
A5C1D2H2I1M1N2O1R2T1

Antworten:


146

Ich stelle fest, dass Sie %like%in Ihrem aktuellen Ansatz eine Funktion erwähnen . Ich weiß nicht, ob das ein Verweis auf die %like%von "data.table" ist, aber wenn ja, können Sie sie definitiv wie folgt verwenden.

Beachten Sie, dass das Objekt kein a sein muss data.table(aber denken Sie auch daran, dass Teilmengenansätze für data.frames und data.tables nicht identisch sind):

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

Wenn Sie das hatten, hatten Sie vielleicht gerade die Zeilen- und Spaltenpositionen für die Teilmenge der Daten vertauscht.


Wenn Sie kein Paket laden möchten, können Sie versuchen, grep()nach der Zeichenfolge zu suchen, mit der Sie übereinstimmen. Hier ist ein Beispiel mit dem mtcarsDatensatz, in dem alle Zeilen abgeglichen werden, in denen der Zeilenname "Merc" enthält:

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

Ein weiteres Beispiel irisfür die Verwendung des Datensatzes, der nach der Zeichenfolge sucht 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

Versuchen Sie für Ihr Problem:

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

+1: Beachten grepSie auch, dass reguläre Ausdrücke unterstützt werden, sodass Sie ^hsa-stattdessen nach grep suchen möchten .
Nico

3
@nico: grepkommt tatsächlich aus dem ed-Befehl g / re / p (global / regulärer Ausdruck / Druck) und offenbart seine wahre Kraft nur dem Meister des regulären Ausdrucks-fu ;-): en.wikipedia.org/ Wiki / Grep
Stephan Kolassa

1
Der % like% Vorschlag ist großartig! Ich empfehle, es ganz oben auf Ihre Antwort zu setzen.
Aren Cambre

@ArenCambre, fertig. Vielleicht hilft es mir, weitere 11 Stimmen zu bekommen, damit ich vor Jahresende einen neuen Hut
bekomme

@ A5C1D2H2I1M1N2O1R2T1 Tolle Antwort! Gibt es eine Möglichkeit,% like% zu verwenden, um nach zwei Zeichenfolgen zu suchen, die zusammen vorkommen (wie in "pet" und "pip", die in einer Zeile eines Datenrahmens als "peter piper" vorkommen)?
nigus21

60

Versuchen Sie es mit str_detect()dem stringr- Paket, das das Vorhandensein oder Fehlen eines Musters in einem String erkennt.

Hier ist ein Ansatz, der auch die %>%Pipe und filter()das dplyr- Paket enthält:

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
...

Dies filtert den CO2-Probendatensatz (der mit R geliefert wird) nach Zeilen, in denen die Behandlungsvariable den Teilstring "non" enthält. Sie können anpassen, ob str_detectfeste Übereinstimmungen gefunden werden oder ein regulärer Ausdruck verwendet wird - siehe Dokumentation zum stringr-Paket.


Sie können auch die Funktion trc_detect wie myDataFrame[str_detect(myDataFrame$key, myKeyPattern),]
folgt verwenden

20

LIKE sollte in SQLite funktionieren:

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 eignet sich am besten zum Auflisten. Es können jedoch keine Zeilen gelöscht werden.
Suat Atan PhD

1
Warum wird ein R - Paket mit geladen require()hier
rgalbo

Da es sich nicht um eine Standard-R-Bibliothek handelt und Sie diese manuell installieren und dann mit der requireFunktion laden müssen.
Bartektartanus
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.