Seleção de linhas de quadro de dados com base na correspondência parcial de string em uma coluna

96

Eu quero selecionar linhas de um quadro de dados com base na correspondência parcial de uma string em uma coluna, por exemplo, a coluna 'x' contém a string "hsa". Usando sqldf- se tivesse uma likesintaxe - eu faria algo como:

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

Infelizmente, sqldf não oferece suporte a essa sintaxe.

Ou da mesma forma:

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

O que, claro, não funciona.

Alguém pode me ajudar com isso?

Asda
fonte
6
Você pode postar algumas linhas de seus dados, de preferência usando algo parecido dput(head(conservedData)).
A5C1D2H2I1M1N2O1R2T1

Respostas:

147

Percebi que você mencionou uma função %like%em sua abordagem atual. Eu não sei se isso é uma referência ao%like% from "data.table", mas se for, você pode definitivamente usá-lo da seguinte maneira.

Observe que o objeto não precisa ser um data.table(mas lembre-se também de que as abordagens de subconjuntos para data.frames e data.tables não são idênticas):

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

Se isso é o que você tinha, então talvez você tenha apenas misturado posições de linha e coluna para subconjunto de dados.


Se não quiser carregar um pacote, você pode tentar usar grep()para pesquisar a string que está correspondendo. Aqui está um exemplo com o mtcarsconjunto de dados, onde estamos combinando todas as linhas em que os nomes das linhas incluem "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, outro exemplo, usando o irisconjunto de dados procurando pela string 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 o seu problema, tente:

selectedRows <- conservedData[grep("hsa-", conservedData$miRNA), ]
A5C1D2H2I1M1N2O1R2T1
fonte
+1: também note que grepsuporta expressões regulares, então você pode querer usar o grep ^hsa-.
nico de
3
@nico: na verdade, grepvem do comando ed g / re / p (global / expressão regular / imprimir), e revela seu poder real apenas para o mestre da expressão regular-fu ;-): en.wikipedia.org/ wiki / Grep
Stephan Kolassa
1
A sugestão % like% é ótima! Eu recomendo colocá-lo no topo de sua resposta.
Aren Cambre
@ArenCambre, pronto. Talvez isso me ajude a conseguir mais 11 votos para que eu possa conseguir um novo chapéu antes do final do ano :-)
A5C1D2H2I1M1N2O1R2T1
@ A5C1D2H2I1M1N2O1R2T1 Ótima resposta! Existe uma maneira de usar% like% para pesquisar duas strings que ocorrem juntas (como em "pet" e "pip" ocorrendo em uma linha de um dataframe como "peter piper")?
nigus21
60

Experimente str_detect()o pacote stringr , que detecta a presença ou ausência de um padrão em uma string.

Aqui está uma abordagem que também incorpora o %>%tubo e filter()do pacote 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
...

Isso filtra o conjunto de dados de amostra de CO2 (que vem com R) para linhas em que a variável de tratamento contém a substring "não". Você pode ajustar se str_detectencontra correspondências fixas ou usa uma regex - consulte a documentação do pacote stringr.

Sam Firke
fonte
Você também pode usar a função trc_detect assimmyDataFrame[str_detect(myDataFrame$key, myKeyPattern),]
Bemipefe
20

LIKE deve funcionar em 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
user1609452
fonte
SQLDF é melhor para listagem. No entanto, ele não pode excluir linhas.
Suat Atan PhD
1
Por que um pacote R está sendo carregado require()aqui
rgalbo
Porque não é uma biblioteca R padrão e você deve instalá-la manualmente e carregá-la usando a requirefunção.
bartektartanus de