从R中的字符串中提取最后n个字符


271

如何从R中的字符串中获取最后n个字符?有没有像SQL的RIGHT这样的函数?

Answers:


281

我不知道基R中的任何内容,但是直接使用substrand 编写一个函数来执行此操作很简单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"

正如@mdsumner指出的那样,这是矢量化的。考虑:

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

1
使用stringi包。它适用于NA和所有编码:)
bartektartanus 2014年

nchar(x)通过将其分配给局部变量来避免两次调用会更有效吗?
Dave Jarvis

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个最后一个字符。
最多

2
stringr不适用于NA的值和所有编码。我强烈推荐stringi包:)
bartektartanus 2014年

3
我认为stringr已经stringi作为后端进行了重新制作,因此现在应该与NAs等一起使用。
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")

安装此软件包。


20
str = 'This is an example'
n = 7
result = substr(str,(nchar(str)+1)-n,nchar(str))
print(result)

> [1] "example"
> 

12

另一种相当直接的方法是使用正则表达式和sub

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

因此,“摆脱所有跟着一个字符的现象”。要从结尾抓取更多字符,请在前瞻断言中添加许多点:

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))
前瞻

10

更新:如mdsumner所述,由于substr是,原始代码已被矢量化。应该多加小心。

如果您想要矢量化版本(基于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

使用该substring()函数的简单基础R解决方案(谁知道该函数甚至存在?):

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个字符。步骤如下:

(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))

这将带来所需的最后一个字符。


3

试试这个:

x <- "some text in a string"
n <- 5
substr(x, nchar(x)-n, nchar(x))

它应该给:

[1] "string"

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"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.