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

370

如何在R中获取字符串的最后n个字符?是否有像SQL的RIGHT函数一样的函数?

15个回答

369

我不知道基本R中是否存在此功能,但使用substrnchar制作一个函数来实现这个功能很简单:

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包。它可以很好地处理NAs和所有编码 :) - bartektartanus
3
nchar(x)分配给一个本地变量,避免两次调用,这样会更有效率吗? - Dave Jarvis
我已经寻找这个东西有一段时间了! - stats_noob
substrRight函数是从哪个包中引入的? - Blaiso
substrRight是上面的一个用户定义函数。 - undefined

303

如果你不介意使用 stringr 包,str_sub 很方便,因为你可以使用负数来倒数计数:

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

正如Max在对本答案的评论中指出的那样,

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

46
另外,str_sub(x,start=-n) 获取最后n个字符。 - Max
2
stringr 不太适用于 NA 值和所有编码。我强烈推荐使用 stringi 包 :) - bartektartanus
4
我认为stringr已经使用stringi作为后端进行了重构,因此现在应该可以处理NA等内容。 - m-dz

58

使用stringi包中的stri_sub函数。 要从结尾获取子字符串,请使用负数。 请参阅以下示例:

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

安装此软件包。


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

> [1] "example"
> 

17

另一个相对简单的方法是使用正则表达式和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)

5
为避免使用所有先行断言等复杂方法,你可以使用 regmatches(x, regexpr(".{6}$", x)) 来实现。该代码可提取字符串 x 中的末尾 6 个字符。 - thelatemail

12

试试这个:

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

它应该给出:

[1] "string"

1
但是这会返回最后6个字符而不是5个。 - drj3122
因此,也许可以使用以下代码:substr(x,nchar(x) -(n-1),nchar(x)) - Markm0705

12

更新:如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

12

使用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,但是我使用不同的方法。我想提取“Give me your food.”的最后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。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接