【问题标题】:How to Reverse a string in R如何在R中反转字符串
【发布时间】:2012-11-28 19:33:18
【问题描述】:

我正在尝试自学 R,并在做一些示例问题时遇到了反转字符串的需要。

这是我到目前为止尝试过的,但粘贴操作似乎没有任何效果。

列表中一定有一些我不理解的地方吗? (我也不明白为什么我在 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"

【问题讨论】:

  • 您正在寻找paste(test_rev, collapse='')
  • @mplourde 我认为它允许paste 像大多数其他 R 函数一样以矢量化方式运行。
  • @joran 是的,谢天谢地,我们不必写do.call(paste, as.list(my.atomic))
  • 看来xkcd.com/1137 在这里合适:-)
  • 为了更好地理解为什么在strsplit() 之后需要[[1]],请尝试运行:X &lt;- strsplit(c("abc", "Statistics"), NULL); X; X[[1]]; X[[2]]

标签: r


【解决方案1】:

来自?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"

【讨论】:

  • 不错,同样的函数重写了 dplyr/magrittr 的可读性strreverse &lt;- function(x){ strsplit(x, NULL) %&gt;% lapply(rev) %&gt;% sapply(paste, collapse="") }
【解决方案2】:

stringi这个功能很久了:

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

还要注意它是矢量化的:

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

【讨论】:

  • 这会反转字符,而不是字符串。
【解决方案3】:

正如@mplourde 指出的那样,您需要collapse 参数:

paste(test_rev, collapse='')

R 中的大多数命令都是矢量化的,但命令处理矢量的准确程度取决于命令。 paste 将对多个向量进行操作,结合每个向量的 ith 元素:

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

collapse 告诉它改为在向量内操作。

【讨论】:

  • 那我为什么要写collapse=''? '' 不会评估为假吗?我不应该说崩溃=真吗? (仍在学习我的 R 基础知识)
  • @Greg paste 有点不标准,我认为您的直觉非常类似于 R。但是,在这种情况下,,collapse 的工作方式与 ,sep 类似,因为它指定了要插入最终字符向量中的字符。试试paste(test_rev, collapse='Whee!') 的插图。
  • @AriB.Friedman 在与paste 折叠后,我得到"c(\"l\", \"o\", \"o\", \"c\")"。但是字符串是cool 怎么了?
【解决方案4】:

以下可能是反转字符串向量x 的有用方法,并且速度稍快(并且内存效率更高),因为它避免了生成列表(如使用strsplit):

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

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

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

【讨论】:

  • 更快的是 str_rev &lt;- function(x) intToUtf8(rev(utf8ToInt(x))) 并将其矢量化(您的 sapply 所做的),执行 str_rev mapply)。您确定sapply 不会将列表创建为中间产品吗?当然,它比strsplit 快。 utf8ToIntintToUtf8 的绝妙技巧 - 谢谢!和rev
【解决方案5】:

您也可以使用IRanges 包。

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

您也可以使用Biostrings 包。

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

【讨论】:

    【解决方案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
    

    【讨论】:

      【解决方案7】:

      这是一个返回整个反转字符串的函数,也可以选择只保留index 指定的元素的反转字符串,从最后一个字符开始倒数。

      revString = function(string, index = 1:nchar(string)){
        paste(rev(unlist(strsplit(string, NULL)))[index], collapse = "")
      }
      

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

      (myString &lt;- paste(letters, collapse = ""))

      [1] "abcdefghijklmnopqrstuvwxyz"

      现在尝试使用和不使用索引的函数revString

      revString(myString)

      [1] "zyxwvutsrqponmlkjihgfedcba"

      revString(myString, 1:5)

      [1] "zyxwv"

      【讨论】:

        【解决方案8】:

        您可以使用上一篇文章中提到的 rev() 函数。

        `X <- "MyString"
        

        RevX &lt;- paste(rev(unlist(strsplit(X,NULL))),collapse="")

        输出:“gnirtSyM”

        谢谢,

        【讨论】:

        • 已经有 25000 次浏览,回答 5 年前的问题毫无意义。你的答案将被埋在没人会看到的地方。而是回答最新的问题
        • 回答老问题没有错。我可以看到他的回答就好了。
        【解决方案9】:

        这是gsub 的解决方案。虽然我同意 strsplitpaste 更容易(正如其他答案中所指出的那样),但看到它也适用于正则表达式可能会很有趣:

        test <- "greg"
        
        n <- nchar(test) # the number of characters in the string
        
        gsub(paste(rep("(.)", n), collapse = ""),
             paste("", seq(n, 1), sep = "\\", collapse = ""),
             test)
        
        # [1] "gerg"
        

        【讨论】:

        • @mvkorpel 这是真的。它更多的是概念的演示,而不是通用的解决方案。
        【解决方案10】:
        ##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"))
        }
        

        【讨论】:

          【解决方案11】:

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

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

          【讨论】:

            【解决方案12】:

            这是另一种 base-R 解决方案:

            # Define function
            strrev <- function(x) {
              nc <- nchar(x)
              paste(substring(x, nc:1, nc:1), collapse = "")
            }
            
            # Example
            strrev("Sore was I ere I saw Eros")
            [1] "sorE was I ere I saw eroS"
            

            解决方案的灵感来自these U. Auckland slides

            【讨论】:

              【解决方案13】:

              以下代码将接受用户输入并反转整个字符串-

              revstring=function(s)
              print(paste(rev(strsplit(s,"")[[1]]),collapse=""))
              
              str=readline("Enter the string:")
              revstring(str)
              

              【讨论】:

                【解决方案14】:

                显然,前端 JS 开发人员被要求在 JS 中执行此操作(用于面试),而不使用内置的反向函数。我花了几分钟,但我想出了:

                string <- 'hello'
                
                foo <- vector()
                
                for (i in nchar(string):1) foo <- append(foo,unlist(strsplit(string,''))[i])
                paste0(foo,collapse='')
                

                这一切都可以包装在一个函数中......

                高阶泛函呢?减少?

                【讨论】:

                  猜你喜欢
                  • 2012-08-02
                  • 2014-02-26
                  • 2016-08-13
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-11-30
                  相关资源
                  最近更新 更多