การเลือกแถวของกรอบข้อมูลตามการจับคู่สตริงบางส่วนในคอลัมน์


101

ฉันต้องการเลือกแถวจากกรอบข้อมูลตามการจับคู่สตริงบางส่วนในคอลัมน์เช่นคอลัมน์ 'x' มีสตริง "hsa" การใช้sqldf- ถ้ามันมีlikeไวยากรณ์ - ฉันจะทำสิ่งที่ชอบ:

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

น่าเสียดายที่sqldfไม่รองรับไวยากรณ์นั้น

หรือในทำนองเดียวกัน:

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

ซึ่งแน่นอนไม่ได้ผล

ใครช่วยฉันด้วยได้ไหม


6
dput(head(conservedData))คุณสามารถโพสต์ไม่กี่บรรทัดของข้อมูลของคุณควรใช้สิ่งที่ต้องการ
A5C1D2H2I1M1N2O1R2T1

คำตอบ:


155

ฉันสังเกตเห็นว่าคุณพูดถึงฟังก์ชัน%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รองรับนิพจน์ทั่วไปดังนั้นคุณอาจต้องการ grep ^hsa-แทน
nico

3
@nico: อันที่จริงแล้วgrepมาจากคำสั่ง ed g / re / p (global / regular expression / print) และมันเผยให้เห็นพลังที่แท้จริงของมันเฉพาะกับผู้เชี่ยวชาญของนิพจน์ทั่วไปเท่านั้น - fu ;-): en.wikipedia.org/ wiki / Grep
Stephan Kolassa

1
% ชอบ%ข้อเสนอแนะที่ดีมาก! ฉันขอแนะนำให้วางไว้ที่ด้านบนของคำตอบของคุณ
Aren Cambre

@ArenCambre เสร็จแล้ว บางทีมันอาจจะช่วยให้ฉันได้รับอีก 11 คะแนนเพื่อที่ฉันจะได้หมวกใหม่ก่อนสิ้นปี :-)
A5C1D2H2I1M1N2O1R2T1

@ A5C1D2H2I1M1N2O1R2T1 ตอบโจทย์มาก! มีวิธีใช้% like% เพื่อค้นหา 2 สตริงที่เกิดขึ้นพร้อมกัน (เช่นเดียวกับ "pet" และ "pip" ที่เกิดขึ้นในแถวของดาต้าเฟรมเป็น "peter piper") หรือไม่
nigus21

63

ลอง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ค้นหาการจับคู่แบบคงที่หรือใช้ regex - ดูเอกสารสำหรับแพ็กเกจ 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 เหมาะที่สุดสำหรับการแสดงรายการ อย่างไรก็ตามไม่สามารถลบแถวได้
Suat Atan PhD

1
เหตุใดแพ็คเกจ R จึงถูกโหลดrequire()ที่นี่
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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.