如何在R中反转字符串

56

我正在尝试自学R语言,在做一些样例问题时,遇到需要反转字符串的情况。

以下是我的尝试,但paste操作似乎没有任何效果。

可能是我对列表的理解还有些欠缺?(我也不明白为什么在strsplit之后需要 [[1]]。)

test <- strsplit("greg", NULL)[[1]]
test
# [1] "g" "r" "e" "g"

test_rev <- rev(test)
test_rev
# [1] "g" "e" "r" "g"

paste(test_rev)
# [1] "g" "e" "r" "g"

12
你正在寻找paste(test_rev, collapse='')的代码。 - Matthew Plourde
3
我认为这样做可以使paste函数像其他大多数R函数一样以矢量化方式运行。 - joran
2
是的 @joran,谢天谢地我们不必编写 do.call(paste, as.list(my.atomic)) - Matthew Plourde
5
似乎http://xkcd.com/1137/在这里很合适 :-) - Carl Witthoft
1
为了更好地理解为什么在 strsplit() 后需要 [[1]],请尝试运行以下代码:X <- strsplit(c("abc", "Statistics"), NULL); X; X[[1]]; X[[2]] - Josh O'Brien
显示剩余3条评论
14个回答

55

使用?strsplit函数,可以将字符串向量中的每个字符串反转:

## a useful function: rev() for strings
strReverse <- function(x)
        sapply(lapply(strsplit(x, NULL), rev), paste, collapse="")
strReverse(c("abc", "Statistics"))
# [1] "cba"        "scitsitatS"

3
为了提高可读性,使用dplyr/magrittr的方式重写了具有相同功能的代码 strreverse <- function(x){ strsplit(x, NULL) %>% lapply(rev) %>% sapply(paste, collapse="") } - Paul Rougieux

40

stringi已经有相当长的时间拥有这个功能:

stringi::stri_reverse("abcdef")
## [1] "fedcba"

需要注意的是它是向量化的:

stringi::stri_reverse(c("a", "ab", "abc"))
## [1] "a"   "ba"  "cba"

1
这个操作是反转字符,而不是字符串。 - jzadra

21

正如 @mplourde 指出的,你需要使用 collapse 参数:

paste(test_rev, collapse='')

R中的大多数命令都是向量化的,但是命令如何处理向量取决于命令本身。 paste 可以作用于多个向量,将每个向量的第 i 个元素组合起来:

> paste(letters[1:5],letters[1:5])
[1] "a a" "b b" "c c" "d d" "e e"

collapse指示它在向量内运行。


那我为什么要写 collapse='' 呢?''不是会被判断为 false 吗?我难道不应该写 collapse=True 吗?(还在学习 R 的基础知识) - Greg
1
@Greg paste有点不太标准,我认为你的直觉完全符合R语言的风格。然而,在这种情况下,,collapse的作用类似于,sep,它指定要插入到最终字符向量中的字符。尝试使用paste(test_rev, collapse='Whee!')进行演示。 - Ari B. Friedman
@AriB.Friedman 在使用 paste 折叠后,我得到了 "c(\"l\", \"o\", \"o\", \"c\")"。但是原本的字符串是 cool。出了什么问题? - user6557479

10

您还可以使用 IRanges 包。

library(IRanges)
x <- "ATGCSDS"
reverse(x)
# [1] "SDSCGTA"

你也可以使用Biostrings包。

library(Biostrings)
x <- "ATGCSDS"
reverse(x)
# [1] "SDSCGTA"

10

以下内容可以是反转字符串向量 x 的有用方法,它稍微更快一些(且更节省内存),因为它避免产生列表(例如使用 strsplit):

x <- rep( paste( collapse="", LETTERS ), 100 )
str_rev <- function(x) {
  sapply( x, function(xx) { 
    intToUtf8( rev( utf8ToInt( xx ) ) )
  } )
}
str_rev(x)

如果您知道您将要使用ASCII字符并且速度很重要,那么在 Kmisc 中有一个快速的C实现可以用来反转字符串向量:

install.packages("Kmisc")
str_rev(x)

更快的方法是 str_rev <- function(x) intToUtf8(rev(utf8ToInt(x))),如果要将其向量化(就像您的sapply所做的那样),则可以使用 str_rev <- Vectorize(str_rev)(但它在幕后使用mapply)。您确定sapply不会创建列表作为中间产品吗?它绝对比strsplit快。utf8ToIntintToUtf8以及rev是很好的技巧 - 谢谢! - Gwang-Jin Kim

6

如果您的数据在一个 data.frame 中,您可以使用 sqldf

myStrings <- data.frame(forward = c("does", "this", "actually", "work"))
library(sqldf)
sqldf("select forward, reverse(forward) `reverse` from myStrings")
#    forward  reverse
# 1     does     seod
# 2     this     siht
# 3 actually yllautca
# 4     work     krow

4
这里是一个函数,它返回整个反转的字符串,或者仅返回指定元素的反转字符串,按照从最后一个字符往回数的顺序计数。
revString = function(string, index = 1:nchar(string)){
  paste(rev(unlist(strsplit(string, NULL)))[index], collapse = "")
}

首先,定义一个易于识别的字符串作为示例:

(myString <- paste(letters, collapse = ""))

[1] "abcdefghijklmnopqrstuvwxyz"

现在尝试使用函数revString, 有和没有索引的情况:

revString(myString)

[1] "zyxwvutsrqponmlkjihgfedcba"

revString(myString, 1:5)

[1] "zyxwv"


4
您可以像之前的帖子中提到的那样使用rev()函数。
`X <- "MyString"

RevX <- paste(rev(unlist(strsplit(X,NULL))),collapse="")

输出结果: "gnirtSyM"

谢谢。


回答已经有25000次浏览量的5年前的问题是没有意义的。你的回答会被埋在一个没有人看到的地方。相反,回答最新的问题。 - Anuraag Baishya
9
回答旧问题没有问题。我可以清楚地看到他的回答。 - DWal

4

反转字符串的最简单方法:

#reverse string----------------------------------------------------------------
revString <- function(text){
  paste(rev(unlist(strsplit(text,NULL))),collapse="")
}

#example:
revString("abcdef")

1
##function to reverse the given word or sentence

reverse <- function(mystring){ 
n <- nchar(mystring)
revstring <- rep(NA, n)
b <- n:1
c <- rev(b)
for (i in 1:n) {
revstring[i] <- substr(mystring,c[(n+1)- i], b[i])
 }
newrevstring <- paste(revstring, sep = "", collapse = "")
return (cat("your string =", mystring, "\n",
("reverse letters = "), revstring, "\n", 
"reverse string =", newrevstring,"\n"))
}

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