Chọn hàng khung dữ liệu dựa trên khớp một phần chuỗi trong một cột


96

Tôi muốn chọn các hàng từ khung dữ liệu dựa trên khớp một phần của chuỗi trong một cột, ví dụ: cột 'x' chứa chuỗi "hsa". Sử dụng sqldf- nếu nó có một likecú pháp - tôi sẽ làm điều gì đó như:

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

Thật không may, sqldfkhông hỗ trợ cú pháp đó.

Hoặc tương tự:

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

Tất nhiên là không hiệu quả.

Ai đó có thể vui lòng giúp tôi với?


6
Bạn có thể đăng một vài dòng dữ liệu của bạn, tốt hơn là sử dụng một cái gì đó như dput(head(conservedData)).
A5C1D2H2I1M1N2O1R2T1

Câu trả lời:


147

Tôi nhận thấy rằng bạn đề cập đến một chức năng %like%trong cách tiếp cận hiện tại của bạn. Tôi không biết đó có phải là tham chiếu đến %like%từ "data.table" không, nhưng nếu có, bạn chắc chắn có thể sử dụng nó như sau.

Lưu ý rằng đối tượng không nhất thiết phải là a data.table(nhưng cũng nên nhớ rằng các cách tiếp cận đặt con cho data.frames và data.tables không giống nhau):

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

Nếu đó là những gì bạn có, thì có lẽ bạn vừa trộn các vị trí hàng và cột để lấy dữ liệu con.


Nếu bạn không muốn tải một gói, bạn có thể thử sử dụng grep()để tìm kiếm chuỗi bạn đang khớp. Đây là một ví dụ với mtcarstập dữ liệu, nơi chúng tôi đang đối sánh tất cả các hàng có tên hàng bao gồm "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

Và, một ví dụ khác, sử dụng iristập dữ liệu tìm kiếm chuỗi 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

Đối với vấn đề của bạn, hãy thử:

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

+1: cũng lưu ý rằng nó grephỗ trợ các biểu thức chính quy, vì vậy bạn có thể muốn grep để ^hsa-thay thế.
nico

3
@nico: trên thực tế, grepxuất phát từ lệnh ed g / re / p (global / regular expression / print) và nó chỉ tiết lộ sức mạnh thực sự của nó đối với bậc thầy của biểu thức chính quy-fu ;-): en.wikipedia.org/ wiki / Grep
Stephan Kolassa

1
Đề xuất % thích% là tuyệt vời! Tôi khuyên bạn nên đặt nó ở đầu câu trả lời của bạn.
Aren Cambre

@ArenCambre, xong rồi. Có lẽ nó sẽ giúp tôi có được thêm 11 phiếu để tôi có thể nhận được một chiếc mũ mới trước khi kết thúc năm :-)
A5C1D2H2I1M1N2O1R2T1

@ A5C1D2H2I1M1N2O1R2T1 Câu trả lời tuyệt vời! Có cách nào để sử dụng% like% để tìm kiếm hai chuỗi xuất hiện cùng nhau (như trong "pet" và "pip" xảy ra trong một hàng của khung dữ liệu là "peter piper") không?
nigus21

60

Thử str_detect()từ gói stringr , gói này sẽ phát hiện sự hiện diện hoặc không có của một mẫu trong một chuỗi.

Đây là một cách tiếp cận kết hợp cả %>%đường ống và filter()từ gói 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
...

Thao tác này lọc tập dữ liệu CO2 mẫu (đi kèm với R) cho các hàng mà biến Xử lý chứa chuỗi con "không". Bạn có thể điều chỉnh việc str_detecttìm các kết quả phù hợp cố định hay sử dụng regex - hãy xem tài liệu về gói stringr.


Bạn cũng có thể sử dụng trc_detect chức năng như thế nàymyDataFrame[str_detect(myDataFrame$key, myKeyPattern),]
Bemipefe

20

LIKE sẽ hoạt động trong 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 là tốt nhất để liệt kê. Tuy nhiên, nó không thể xóa các hàng.
Tiến sĩ Suat Atan

1
Tại sao một gói R được nạp với require()ở đây
rgalbo

Bởi vì nó không phải là thư viện R tiêu chuẩn và bạn phải cài đặt thủ công nó và sau đó tải bằng requirechức năng.
bartektartanus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.