แยกอักขระ n ตัวสุดท้ายออกจากสตริงใน R


271

ฉันจะรับตัวอักษร n ตัวสุดท้ายจากสตริงใน R ได้อย่างไร? มีฟังก์ชั่นอย่าง SQL ที่เหมาะสมหรือไม่?

คำตอบ:


283

ฉันไม่รู้อะไรเลยในฐาน R แต่มันตรงไปตรงมาที่จะทำให้ฟังก์ชั่นนี้ใช้งานได้substrและnchar:

x <- "some text in a string"

substrRight <- function(x, n){
  substr(x, nchar(x)-n+1, nchar(x))
}

substrRight(x, 6)
[1] "string"

substrRight(x, 8)
[1] "a string"

นี่คือ vectorised เนื่องจาก @mdsumner ชี้ให้เห็น พิจารณา:

x <- c("some text in a string", "I really need to learn how to count")
substrRight(x, 6)
[1] "string" " count"

1
ใช้แพ็คเกจ stringi มันทำงานได้ดีกับ NAS และการเข้ารหัสทั้งหมด :)
bartektartanus

มันจะมีประสิทธิภาพมากขึ้นหรือไม่ในการหลีกเลี่ยงการโทรnchar(x)สองครั้งโดยการกำหนดให้กับตัวแปรท้องถิ่นหรือไม่?
เดฟจาร์วิส

206

หากคุณไม่รังเกียจการใช้stringrแพ็คเกจstr_subนี้มีประโยชน์เพราะคุณสามารถใช้ฟิล์มเนกาทีฟนับถอยหลัง:

x <- "some text in a string"
str_sub(x,-6,-1)
[1] "string"

หรือตามที่ Max ชี้ให้เห็นในความคิดเห็นต่อคำตอบนี้

str_sub(x, start= -6)
[1] "string"

32
และ str_sub (x, start = -n) รับ n อักขระตัวสุดท้าย
Max

2
stringr ทำงานได้ไม่ดีกับคุณค่าของ NA และการเข้ารหัสทั้งหมด ฉันขอแนะนำแพคเกจ stringi :)
bartektartanus

3
ฉันเชื่อว่าstringrได้รับการจัดแจงใหม่เพื่อใช้stringiเป็นแบ็กเอนด์ดังนั้นควรทำงานกับ NA ฯลฯ ในตอนนี้
m-dz

44

ใช้stri_subฟังก์ชั่นจากstringiแพ็คเกจ ในการรับซับสตริงจากท้ายที่สุดให้ใช้จำนวนลบ ดูตัวอย่างด้านล่าง:

stri_sub("abcde",1,3)
[1] "abc"
stri_sub("abcde",1,1)
[1] "a"
stri_sub("abcde",-3,-1)
[1] "cde"

คุณสามารถติดตั้งแพคเกจนี้ได้จาก github: https://github.com/Rexamine/stringi

มันมีอยู่ใน CRAN แล้วเพียงพิมพ์

install.packages("stringi")

เพื่อติดตั้งแพ็คเกจนี้



12

อีกวิธีที่ตรงไปตรงมาอย่างสมเหตุสมผลคือการใช้นิพจน์ทั่วไปและsub:

sub('.*(?=.$)', '', string, perl=T)

ดังนั้น "กำจัดทุกสิ่งตามด้วยตัวละครตัวหนึ่ง" ในการหยิบตัวละครออกมาให้มากที่สุดให้เพิ่มจุดจำนวนมากลงในการยืนยันแบบ lookahead:

sub('.*(?=.{2}$)', '', string, perl=T)

โดยที่.{2}หมายถึง..หรือ "อักขระสองตัว" ดังนั้นความหมาย "กำจัดทุกสิ่งตามด้วยอักขระสองตัว"

sub('.*(?=.{3}$)', '', string, perl=T)

สำหรับสามตัวละคร ฯลฯ คุณสามารถตั้งค่าจำนวนตัวอักษรเพื่อจับกับตัวแปร แต่คุณจะต้องมีpasteค่าตัวแปรในสตริงการแสดงออกปกติ:

n = 3
sub(paste('.+(?=.{', n, '})', sep=''), '', string, perl=T)

2
เพื่อหลีกเลี่ยงการมองหัวทั้งหมด ฯลฯ คุณสามารถทำได้regmatches(x, regexpr(".{6}$", x))
thelatemail

10

UPDATE : ตามที่บันทึกไว้โดยmdsumnerรหัสต้นฉบับจะถูก vectorised แล้วเพราะ substr เป็น ควรระวังให้มากขึ้น

และถ้าคุณต้องการเวอร์ชั่น vectorised (ตามรหัสของAndrie )

substrRight <- function(x, n){
  sapply(x, function(xx)
         substr(xx, (nchar(xx)-n+1), nchar(xx))
         )
}

> substrRight(c("12345","ABCDE"),2)
12345 ABCDE
 "45"  "DE"

โปรดทราบว่าฉันมีการเปลี่ยนแปลง(nchar(x)-n)เพื่อ(nchar(x)-n+1)ที่จะได้รับnตัวละคร


ฉันคิดว่าคุณหมายถึง " (nchar(x)-n)ถึง(nchar(x)-n+1)"
Xu Wang

8

โซลูชัน R พื้นฐานแบบง่าย ๆ ที่ใช้substring()ฟังก์ชัน (ใครจะรู้ว่ามีฟังก์ชั่นนี้อยู่บ้าง):

RIGHT = function(x,n){
  substring(x,nchar(x)-n+1)
}

สิ่งนี้ใช้ประโยชน์จากการsubstr()อยู่ภายใต้พื้นแต่มีค่าเริ่มต้นสิ้นสุดที่ 1,000,000

ตัวอย่าง:

> RIGHT('Hello World!',2)
[1] "d!"
> RIGHT('Hello World!',8)
[1] "o World!"

6

อีกทางเลือกหนึ่งsubstrคือการแยกสตริงลงในรายการอักขระเดี่ยวและกระบวนการที่:

N <- 2
sapply(strsplit(x, ""), function(x, n) paste(tail(x, n), collapse = ""), N)

6
ฉันรู้สึกถึง system.time () การต่อสู้กับการต้มเบียร์ :-)
Carl Witthoft

4

ฉันก็ใช้substrเหมือนกัน แต่ในวิธีที่ต่างออกไป ฉันต้องการแยกอักขระ 6 ตัวสุดท้ายของ "Give me your food" นี่คือขั้นตอน:

(1) แยกตัวละคร

splits <- strsplit("Give me your food.", split = "")

(2) แยกอักขระ 6 ตัวสุดท้าย

tail(splits[[1]], n=6)

เอาท์พุท:

[1] " " "f" "o" "o" "d" "."

อักขระแต่ละตัวสามารถเข้าถึงได้โดยsplits[[1]][x]ที่ x คือ 1 ถึง 6


3

บางคนก่อนหน้านี้ใช้โซลูชันที่คล้ายกันกับฉัน แต่ฉันคิดว่าง่ายกว่าที่จะคิดดังนี้:

> text<-"some text in a string" # we want to have only the last word "string" with 6 letter
> n<-5 #as the last character will be counted with nchar(), here we discount 1
> substr(x=text,start=nchar(text)-n,stop=nchar(text))

วิธีนี้จะนำอักขระตัวสุดท้ายตามต้องการ



1

ฉันใช้รหัสต่อไปนี้เพื่อรับอักขระตัวสุดท้ายของสตริง

    substr(output, nchar(stringOfInterest), nchar(stringOfInterest))

คุณสามารถเล่นกับ nchar (stringOfInterest) เพื่อหาวิธีรับตัวอักษรสองสามตัวสุดท้าย


0

การปรับเปลี่ยนเล็กน้อยในโซลูชัน @Andrie ให้ส่วนเสริมดังนี้:

substrR <- function(x, n) { 
  if(n > 0) substr(x, (nchar(x)-n+1), nchar(x)) else substr(x, 1, (nchar(x)+n))
}
x <- "moSvmC20F.5.rda"
substrR(x,-4)
[1] "moSvmC20F.5"

นั่นคือสิ่งที่ฉันกำลังมองหา และมันชวนไปทางซ้าย:

substrL <- function(x, n){ 
  if(n > 0) substr(x, 1, n) else substr(x, -n+1, nchar(x))
}
substrL(substrR(x,-4),-2)
[1] "SvmC20F.5"

0

ในกรณีที่ต้องเลือกช่วงของอักขระ:

# For example, to get the date part from the string

substrRightRange <- function(x, m, n){substr(x, nchar(x)-m+1, nchar(x)-m+n)}

value <- "REGNDATE:20170526RN" 
substrRightRange(value, 10, 8)

[1] "20170526"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.