สมมติว่าฉันมีรายการสตริง:
string = c("G1:E001", "G2:E002", "G3:E003")
ตอนนี้ผมหวังว่าจะได้เวกเตอร์ของสตริงที่มีเพียงชิ้นส่วนหลังจากลำไส้ใหญ่ ":" substring = c(E001,E002,E003)
คือ
มีวิธีที่สะดวกใน R ในการดำเนินการนี้หรือไม่? ใช้substr
?
สมมติว่าฉันมีรายการสตริง:
string = c("G1:E001", "G2:E002", "G3:E003")
ตอนนี้ผมหวังว่าจะได้เวกเตอร์ของสตริงที่มีเพียงชิ้นส่วนหลังจากลำไส้ใหญ่ ":" substring = c(E001,E002,E003)
คือ
มีวิธีที่สะดวกใน R ในการดำเนินการนี้หรือไม่? ใช้substr
?
คำตอบ:
วิธีการดังต่อไปนี้:
1) ย่อย
sub(".*:", "", string)
## [1] "E001" "E002" "E003"
2) strsplit
sapply(strsplit(string, ":"), "[", 2)
## [1] "E001" "E002" "E003"
3) read.table
read.table(text = string, sep = ":", as.is = TRUE)$V2
## [1] "E001" "E002" "E003"
4) สตริงย่อย
สิ่งนี้ถือว่าส่วนที่สองเริ่มต้นที่อักขระที่ 4 เสมอ (ซึ่งเป็นกรณีตัวอย่างในคำถาม):
substring(string, 4)
## [1] "E001" "E002" "E003"
4a) สตริงย่อย / นิพจน์ทั่วไป
หากลำไส้ใหญ่ไม่อยู่ในตำแหน่งที่ทราบเสมอไปเราสามารถแก้ไข (4) โดยค้นหา:
substring(string, regexpr(":", string) + 1)
5) strapplyc
strapplyc
ส่งคืนส่วนในวงเล็บ:
library(gsubfn)
strapplyc(string, ":(.*)", simplify = TRUE)
## [1] "E001" "E002" "E003"
6) read.dcf
สิ่งนี้ใช้ได้เฉพาะเมื่อสตริงย่อยก่อนโคลอนไม่ซ้ำกัน (ซึ่งอยู่ในตัวอย่างในคำถาม) นอกจากนี้ยังกำหนดให้ตัวคั่นเป็นโคลอน (ซึ่งอยู่ในคำถาม) หากใช้ตัวคั่นอื่นเราสามารถใช้sub
เพื่อแทนที่ด้วยเครื่องหมายจุดคู่ก่อน ตัวอย่างเช่นถ้าแยกได้_
แล้วstring <- sub("_", ":", string)
c(read.dcf(textConnection(string)))
## [1] "E001" "E002" "E003"
7) แยกกัน
7a)การใช้tidyr::separate
เราสร้าง data frame ที่มีสองคอลัมน์โดยหนึ่งสำหรับส่วนก่อนโคลอนและอีกอันสำหรับ after จากนั้นแยกส่วนหลังออก
library(dplyr)
library(tidyr)
library(purrr)
DF <- data.frame(string)
DF %>%
separate(string, into = c("pre", "post")) %>%
pull("post")
## [1] "E001" "E002" "E003"
7b)separate
สามารถใช้อีกวิธีหนึ่งเพื่อสร้างpost
คอลัมน์จากนั้นunlist
และunname
กรอบข้อมูลผลลัพธ์:
library(dplyr)
library(tidyr)
DF %>%
separate(string, into = c(NA, "post")) %>%
unlist %>%
unname
## [1] "E001" "E002" "E003"
8) trimwsเราสามารถใช้trimws
เพื่อตัดอักขระคำออกทางซ้ายแล้วใช้อีกครั้งเพื่อตัดลำไส้ใหญ่
trimws(trimws(string, "left", "\\w"), "left", ":")
## [1] "E001" "E002" "E003"
ข้อมูลที่ป้อนstring
จะถือว่า:
string <- c("G1:E001", "G2:E002", "G3:E003")
ตัวอย่างเช่นการใช้gsub
หรือsub
gsub('.*:(.*)','\\1',string)
[1] "E001" "E002" "E003"
นี่เป็นอีกคำตอบง่ายๆ
gsub("^.*:","", string)
ช่วงสายของงานปาร์ตี้ แต่สำหรับคนรุ่นหลังแพ็คเกจstringr (ส่วนหนึ่งของชุดแพ็คเกจ "tidyverse" ยอดนิยม) มีฟังก์ชันที่มีลายเซ็นที่กลมกลืนกันสำหรับการจัดการสตริง:
string <- c("G1:E001", "G2:E002", "G3:E003")
# match string to keep
stringr::str_extract(string = string, pattern = "E[0-9]+")
# [1] "E001" "E002" "E003"
# replace leading string with ""
stringr::str_remove(string = string, pattern = "^.*:")
# [1] "E001" "E002" "E003"
สิ่งนี้ควรทำ:
gsub("[A-Z][1-9]:", "", string)
ให้
[1] "E001" "E002" "E003"
หากคุณกำลังใช้data.table
แล้วtstrsplit()
เป็นทางเลือกธรรมชาติ
tstrsplit(string, ":")[[2]]
[1] "E001" "E002" "E003"
unglueแพคเกจให้ทางเลือกที่ไม่มีความรู้เกี่ยวกับการแสดงออกปกติเป็นสิ่งจำเป็นสำหรับกรณีที่เรียบง่ายที่นี่เราจะทำ:
# install.packages("unglue")
library(unglue)
string = c("G1:E001", "G2:E002", "G3:E003")
unglue_vec(string,"{x}:{y}", var = "y")
#> [1] "E001" "E002" "E003"
สร้างเมื่อ 2019-11-06 โดยแพ็คเกจ reprex (v0.3.0)
ข้อมูลเพิ่มเติม: https://github.com/moodymudskipper/unglue/blob/master/README.md
อีกวิธีในการแยกสตริงย่อย
library(stringr)
substring <- str_extract(string, regex("(?<=:).*"))
#[1] "E001" "E002" "E003
(?<=:)
: มองไปข้างหลังลำไส้ใหญ่ ( :
)
_
ตัวคั่นและสร้างตัวแปรสองตัวแยกกันสำหรับคำนำหน้าและคำต่อท้ายตามคำตอบของ @Grothendieck:prefix <- sub("_.*", "", variable)
และsuffix <- sub(".*_", "", variable)