Выбор строк фрейма данных на основе частичного совпадения строк в столбце


99

Я хочу выбрать строки из фрейма данных на основе частичного совпадения строки в столбце, например, столбец «x» содержит строку «hsa». Используя sqldf- если бы у него был likeсинтаксис - я бы сделал что-то вроде:

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

К сожалению, sqldfне поддерживает этот синтаксис.

Или аналогично:

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

Что, конечно, не работает.

Может кто-нибудь помочь мне с этим?


6
Можете ли вы опубликовать несколько строк своих данных, желательно используя что-то вроде dput(head(conservedData)).
A5C1D2H2I1M1N2O1R2T1

Ответы:


151

Я заметил, что вы упоминаете функцию %like%в своем текущем подходе. Я не знаю, является ли это ссылкой на %like%from "data.table", но если это так, вы определенно можете использовать его следующим образом.

Обратите внимание, что объект не обязательно должен быть a data.table(но также помните, что подходы к подмножеству data.frames и data.tables не идентичны):

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

Если это то, что у вас было, то, возможно, вы просто перепутали позиции строк и столбцов для разделения данных.


Если вы не хотите загружать пакет, вы можете попробовать использовать grep()для поиска совпадающей строки. Вот пример с mtcarsнабором данных, где мы сопоставляем все строки, имена которых включают "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

И еще один пример, использующий irisнабор данных для поиска строки 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

Для вашей проблемы попробуйте:

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

+1: также обратите внимание, что grepподдерживает регулярные выражения, поэтому ^hsa-вместо этого вы можете использовать grep for .
Нико

3
@nico: фактически, grepпроисходит от команды ed g / re / p (global / regular expression / print), и она раскрывает свою реальную силу только мастеру регулярного выражения-fu ;-): en.wikipedia.org/ wiki / Grep
Стефан Коласса

1
Предложение % like% отличное! Я рекомендую поставить его в начале вашего ответа.
Aren Cambre

@ArenCambre, готово. Может быть, это поможет мне получить еще 11 голосов, чтобы получить новую шляпу до конца года :-)
A5C1D2H2I1M1N2O1R2T1

@ A5C1D2H2I1M1N2O1R2T1 Отличный ответ! Есть ли способ использовать% like% для поиска двух строк, которые встречаются вместе (например, «pet» и «pip», встречающиеся в строке фрейма данных как «peter piper»)?
nigus21

62

Попробуйте str_detect()из stringr пакета, который определяет наличие или отсутствие шаблона в строке.

Вот подход, который также включает %>%канал и filter()из пакета 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
...

Это фильтрует образец набора данных CO2 (который идет с R) для строк, в которых переменная Treatment содержит подстроку «non». Вы можете настроить str_detectпоиск фиксированных совпадений или использование регулярного выражения - см. Документацию к пакету stringr.


Вы можете также использовать trc_detect функцию , как этоmyDataFrame[str_detect(myDataFrame$key, myKeyPattern),]
Bemipefe

21

LIKE должен работать в 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 лучше всего подходит для перечисления. Однако он не может удалять строки.
Суат Атан PhD

1
Почему require()здесь загружается пакет R
rgalbo

Потому что это не стандартная библиотека R, и вам нужно вручную установить ее, а затем загрузить с помощью requireфункции.
bartektartanus

0

Другой вариант - просто использовать greplфункцию:

df[grepl('er', df$name), ]
CO2[grepl('non', CO2$Treatment), ]

df <- data.frame(name = c('bob','robert','peter'),
                 id = c(1,2,3)
                 )

# name id
# 2 robert  2
# 3  peter  3
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.