2013-07-28 43 views
5

Leapfrogging từ câu hỏi trước, tôi gặp sự cố với cú pháp biểu thức chính xác thích hợp để tách riêng một từ cụ thể.Trích xuất một từ cụ thể bằng gsub và regex

Cho một khung dữ liệu:

DL<-c("Dark_ark","Light-Lis","dark7","DK_dark","The_light","Lights","Lig_dark","D_Light") 
Col1<-c(1,12,3,6,4,8,2,8) 
DF<-data.frame(Col1) 
row.names(DF)<-DL 

Tôi đang tìm chiết xuất tất cả các "Dark" và "Ánh sáng" (bỏ qua trên vs chữ thường) từ những cái tên hàng và thực hiện một cột thứ hai chỉ chứa các chuỗi "Dark" hoặc "Light"

Col2<-c("Dark","Light","dark","dark","light","Light","dark","Light") 
DF$Col2<-Col2 

      Col1 Col2 
Dark_ark  1 Dark 
Light-Lis 12 Light 
dark7  3 dark 
DK_dark  6 dark 
The_light 4 light 
Lights  8 Light 
Lig_dark  2 dark 
D_Light  8 Light 

Ive thay đổi dữ liệu gốc một chút đến từng chi tiết vấn đề hiện tại của tôi, nhưng làm việc của một câu trả lời tuyệt vời từ Tyler Rinker, tôi sử dụng này:

DF$Col2<-gsub("[^dark|light]", "", row.names(DF), ignore.case = TRUE) 

Nhưng gsub bị vấp phải trên một số chữ cái chung. Tìm kiếm trên bảng tin để cô lập một từ chính xác với regex, có vẻ như câu trả lời nên được sử dụng dấu gạch chéo kép với một trong hai

\\<light\\> 

hoặc

\\blight\\b 

Vì vậy, tại sao dòng

DF$Col2<-gsub("[^\\<dark\\>|\\<light\\>]", "", row.names(DF), ignore.case = TRUE) 

Không kéo cột mong muốn ở trên? Thay vào đó, tôi nhận được

  Col1 Col2 
Dark_ark  1 Darkark 
Light-Lis 12 LightLi 
dark7  3 dark 
DK_dark  6 DKdark 
The_light 4 Thlight 
Lights  8 Light 
Lig_dark  2 Ligdark 
D_Light  8 DLight 
+1

Không ai sẽ trả lời một câu hỏi regex nếu nó không phải là [ssce] (http://sscce.org) – aaronman

+1

Đầu tiên, '\\ b' được sử dụng để xác định ranh giới từ. Vì vậy, bạn sẽ phải cho biết chuỗi chính xác ở giữa. Bạn không thể phủ nhận nó afaiu. Thứ hai, nó sử dụng dấu cách và dấu chấm câu để tìm ranh giới ... và '_' không phải là một trong số chúng. – Arun

Trả lời

9

Làm thế nào về điều này?

unlist(regmatches(rownames(DF), gregexpr("dark|light", rownames(DF), ignore.case=TRUE))) 
# [1] "Dark" "Light" "dark" "dark" "light" "Light" "dark" "Light" 

hoặc

gsub(".*(dark|light).*$", "\\1", row.names(DF), ignore.case = TRUE) 
# [1] "Dark" "Light" "dark" "dark" "light" "Light" "dark" "Light" 
+0

Mặc dù hơi mạo hiểm trong thực tế chung, và do 'as.character' làm việc theo cách của nó, bạn có thể làm cho cái đầu tiên:' tolower (regmatches (rownames (DF), gregexpr ("dark | light", rownames (DF), ignore.case = TRUE))) ' – thelatemail

+0

.... và được cho là thứ hai sẽ cho kết quả nhất quán hơn với:' gsub (". * (dark | light). * $", "\\ 1", tolower (row.names (DF))) ' – thelatemail

+0

@thelatemail, kết quả được hiển thị bởi OP có, ví dụ, cả" Dark "và" dark "tùy thuộc vào cái nào có mặt trong rownames. Do đó sự vắng mặt của 'tolower' trong câu trả lời. – Arun

5

Một lựa chọn là sử dụng stringr gói:

library(stringr) 
str_extract(tolower(rownames(DF)),'dark|light') 
[1] "dark" "light" "dark" "dark" "light" "light" "dark" "light" 

Hoặc tốt hơn sử dụng gợi ý @Arun:

str_extract(rownames(DF), ignore.case('dark|light')) 
+2

agstudy, có vẻ như bạn có thể làm: 'str_extract (rownames (DF), bỏ qua.case ('tối | ánh sáng')) ' – Arun

+0

@Arun xuất sắc. chính xác những gì tôi đã cố gắng làm. – agstudy

Các vấn đề liên quan