Вибір рядків кадру даних на основі часткового збігу рядків у стовпці


97

Я хочу вибрати рядки з кадру даних на основі часткового збігу рядка у стовпці, наприклад стовпець 'x' містить рядок "hsa". Використовуючи sqldf- якби він мав likeсинтаксис - я б зробив щось на зразок:

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

На жаль, sqldfне підтримує цей синтаксис.

Або так само:

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

Що, звичайно, не працює.

Хтось може допомогти мені в цьому?


6
Чи можете ви опублікувати кілька рядків своїх даних, бажано, використовуючи щось на зразок dput(head(conservedData)).
A5C1D2H2I1M1N2O1R2T1

Відповіді:


149

Я помічаю, що ви згадали функцію %like%у своєму поточному підході. Я не знаю, чи це посилання на %like%з "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 .
Ніко

3
@nico: насправді grepпоходить від команди ed g / re / p (глобальний / регулярний вираз / друк), і вона розкриває свою справжню силу лише майстру регулярного виразу-fu ;-): en.wikipedia.org/ wiki / Grep
Stephan Kolassa

1
Пропозиція % like% - чудова! Рекомендую помістити його у верхній частині своєї відповіді.
Aren Cambre

@ArenCambre, готово. Можливо, це допоможе мені отримати ще 11 голосів, щоб я міг отримати новий капелюх до кінця року :-)
A5C1D2H2I1M1N2O1R2T1

@ A5C1D2H2I1M1N2O1R2T1 Чудова відповідь! Чи є спосіб використовувати% like% для пошуку двох рядків, які трапляються разом (як у "домашня тварина" та "піп", що трапляються в рядку кадру даних як "пітер-піпер")?
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) для рядків, де змінна обробки містить підрядок "non". Ви можете налаштувати, чи str_detectзнаходить фіксовані збіги чи використовує регулярний вираз - див. Документацію до пакета stringr.


Ви також можете використовувати функцію trc_detect ось такmyDataFrame[str_detect(myDataFrame$key, myKeyPattern),]
Беміпефе

20

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 найкраще підходить для переліку. Однак він не може видалити рядки.
Суат Атан, доктор філософії,

1
Чому require()тут завантажується пакет R
rgalbo

Оскільки це не стандартна бібліотека R, вам доведеться вручну встановити її, а потім завантажити за допомогою requireфункції.
bartektartanus
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.