【问题标题】:How can two strings be concatenated?如何连接两个字符串?
【发布时间】:2011-11-04 07:20:47
【问题描述】:

如何连接(合并、组合)两个值? 例如我有:

tmp = cbind("GAD", "AB")
tmp
#      [,1]  [,2]
# [1,] "GAD" "AB"

我的目标是将“tmp”中的两个值连接成一个字符串:

tmp_new = "GAD,AB"

哪个函数可以为我做到这一点?

【问题讨论】:

  • 如果字符串是向量,这里的大多数答案都会中断,就像@RichardScriven 的回答笔记一样。
  • @smci 我发布的小答案怎么样?有什么改进的建议吗?

标签: r string-concatenation r-faq


【解决方案1】:
paste()

是要走的路。正如之前的海报所指出的,粘贴可以做两件事:

将值连接成一个“字符串”,例如

> paste("Hello", "world", sep=" ")
[1] "Hello world"

其中参数sep 指定要在要连接的参数之间使用的字符, 或折叠字符向量

> x <- c("Hello", "World")
> x
[1] "Hello" "World"
> paste(x, collapse="--")
[1] "Hello--World"

其中参数collapse 指定要在要折叠的向量的元素之间使用的字符。

您甚至可以将两者结合起来:

> paste(x, "and some more", sep="|-|", collapse="--")
[1] "Hello|-|and some more--World|-|and some more"

【讨论】:

  • 混合字符串和向量或不同长度的向量在paste() 中有点太灵活了,我不喜欢。例如,paste(c('a','b'),'blah', c(1,2,3)) 的结果是 "a blah 1" "b blah 2" "a blah 3"。基本上,它创建一个与传入的最长向量长度相同的字符串向量,并将其他向量/字符串循环到相同长度。那里有很多意外行为的空间。
  • 是的 - 但您能否提供解决该问题的替代方法?
  • 否 - 您的答案是正确的(与大多数其他答案相同)。我只是注意到 paste 的行为在其灵活性方面是不同寻常的。
  • @naught101 按照 R 的标准,我不会认为它不寻常。向量循环是 R 函数的一个共同属性。请记住,'blah' 是一个长度为 1 的向量。回收属性可以很容易地执行 paste0("blah", 1:3) 之类的操作以获取 "blah1" "blah2" "blah3"
  • 是的,我应该抱怨 R,而不仅仅是粘贴 :P 。它实际上在 R 中是不一致的 - 如果向量不是彼此的倍数,data.frame() 不允许你这样做。 matrix() 会发出警告,但 array() 不会。有点烦人。真的,除非设置了某些选项,否则它们都应该发出警告......
【解决方案2】:

help.search() 是一个方便的函数,例如

> help.search("concatenate")

会带你到paste()

【讨论】:

    【解决方案3】:

    对于第一个非paste() 的答案,我们可以查看stringr::str_c()(然后是下面的toString())。它的存在时间不长这个问题,所以我认为提及它也存在是有用的。

    如您所见,使用起来非常简单。

    tmp <- cbind("GAD", "AB")
    library(stringr)
    str_c(tmp, collapse = ",")
    # [1] "GAD,AB"
    

    从它的文档文件描述来看,它很好地解决了这个问题。

    要了解 str_c 的工作原理,您需要想象您正在构建一个字符串矩阵。每个输入参数形成一列,并使用通常的循环规则扩展为最长参数的长度。 sep 字符串插入在每列之间。如果 collapse 为 NULL,则每行都折叠成一个字符串。如果非 NULL,则在每行的末尾插入该字符串,并且整个矩阵折叠为单个字符串。

    添加于 2016 年 4 月 13 日:它与您想要的输出(额外空间)不完全相同,但也没有人提到它。 toString() 基本上是 paste() 的一个版本,带有 collapse = ", " 硬编码,所以你可以这样做

    toString(tmp)
    # [1] "GAD, AB"
    

    【讨论】:

    • 嘿,这是解决 tmp 是一个向量,而不仅仅是一堆值这一事实的唯一答案 - paste 不做向量。另一个选项是do.call(paste, as.list(tmp))
    【解决方案4】:

    正如其他人指出的那样,paste() 是要走的路。但是每次需要非默认分隔符时都必须输入paste(str1, str2, str3, sep='') 会很烦人。

    您可以非常轻松地创建包装函数,让生活变得更加简单。例如,如果你发现自己经常连接没有分隔符的字符串,你可以这样做:

    p <- function(..., sep='') {
        paste(..., sep=sep, collapse=sep)
    }
    

    或者如果您经常想要连接来自向量的字符串(例如 PHP 中的 implode()):

    implode <- function(..., sep='') {
         paste(..., collapse=sep)
    }
    

    允许您这样做:

    p('a', 'b', 'c')
    #[1] "abc"
    vec <- c('a', 'b', 'c')
    implode(vec)
    #[1] "abc"
    implode(vec, sep=', ')
    #[1] "a, b, c"
    

    此外,还有内置的paste0,它与我的implode 做同样的事情,但不允许自定义分隔符。比paste() 稍微高效一点。

    【讨论】:

      【解决方案5】:
      > tmp = paste("GAD", "AB", sep = ",")
      > tmp
      [1] "GAD,AB"
      

      我通过搜索 R 连接字符串从 Google 找到了这个http://stat.ethz.ch/R-manual/R-patched/library/base/html/paste.html

      【讨论】:

        【解决方案6】:

        或者,如果您的目标是直接输出到文件或标准输出,您可以使用cat

        cat(s1, s2, sep=", ")
        

        【讨论】:

        • 那么在 4 年后已经有大约十几个 paste 答案发布 paste 答案有什么意义?
        • 当时我发现自己总结多个答案很有帮助。目的不是收集选票,而是帮助其他人通过提供的许多解决方案进行筛选。通常这就是我想要的。
        • @DavidArenburg 你的评论有什么意义?
        • @Error404 关键是要防止重复的答案——这不是很明显吗?如果你会发布一个答案,我会在 4 年后来并在同一个线程上重新发布你的答案,这有意义吗?
        【解决方案7】:

        您可以创建自己的运营商:

        '%&%' <- function(x, y)paste0(x,y)
        "new" %&% "operator"
        [1] newoperator`
        

        您还可以重新定义“和”(&amp;) 运算符:

        '&' <- function(x, y)paste0(x,y)
        "dirty" & "trick"
        "dirtytrick"
        

        混淆基线语法是丑陋的,但使用paste()/paste0() 也是如此,如果你只使用自己的代码,你可以(几乎总是)用* 替换逻辑&amp; and 运算符并进行逻辑值的乘法而不是使用逻辑“和&”

        【讨论】:

        • @Richard Scriven mayby 我不明白,但看起来很简单,比较一下:paste0(as.matrix(iris[1:4]) , as.matrix(iris[1:4]))as.matrix(iris[1:4]) %&amp;% as.matrix(iris[1:4])
        • 非常非常好! & 是许多语言中连接的标准,我实际上认为 R 应该默认拥有它。强烈推荐这种方式
        【解决方案8】:

        另一种方式:

        sprintf("%s you can add other static strings here %s",string1,string2)
        

        它有时比paste() 函数有用。 %s 表示将包含主观字符串的位置。

        请注意,这将在您尝试构建路径时派上用场:

        sprintf("/%s", paste("this", "is", "a", "path", sep="/"))
        

        输出

        /this/is/a/path
        

        【讨论】:

        • 对于处理 R 的 C 程序员来说,sprintf 对于“连接两个字符串”很熟悉并且很有用
        • 恕我直言好多了。 paste 不够灵活,如果你想在字符串中附加一些东西。
        【解决方案9】:

        给定您创建的矩阵 tmp:

        paste(tmp[1,], collapse = ",")
        

        我认为您使用 cbind 创建矩阵是有原因的,而不是简单地:

        tmp <- "GAD,AB"
        

        【讨论】:

          【解决方案10】:

          考虑字符串是列并且结果应该是新列的情况:

          df <- data.frame(a = letters[1:5], b = LETTERS[1:5], c = 1:5)
          
          df$new_col <- do.call(paste, c(df[c("a", "b")], sep = ", ")) 
          df
          #  a b c new_col
          #1 a A 1    a, A
          #2 b B 2    b, B
          #3 c C 3    c, C
          #4 d D 4    d, D
          #5 e E 5    e, E
          

          (可选)如果需要粘贴所有列,则跳过 [c("a", "b")] 子集。

          # you can also try str_c from stringr package as mentioned by other users too!
          do.call(str_c, c(df[c("a", "b")], sep = ", ")) 
          

          【讨论】:

          • 好的,但是stringi, stringr 库更快。
          【解决方案11】:

          glue 是作为tidyverse 的一部分开发的新函数、数据类和包,具有许多扩展功能。它结合了 paste、sprintf 和以前的其他答案的功能。

          tmp <- tibble::tibble(firststring = "GAD", secondstring = "AB")
          (tmp_new <- glue::glue_data(tmp, "{firststring},{secondstring}"))
          #> GAD,AB
          

          reprex package (v0.2.1) 于 2019 年 3 月 6 日创建

          是的,对于这个问题中的简单示例来说,这有点矫枉过正,但在许多情况下都很强大。 (见https://glue.tidyverse.org/

          paste 和下面的with 相比的快速示例。 glue 代码更容易输入,看起来也更容易阅读。

          tmp <- tibble::tibble(firststring = c("GAD", "GAD2", "GAD3"), secondstring = c("AB1", "AB2", "AB3"))
          (tmp_new <- glue::glue_data(tmp, "{firststring} and {secondstring} went to the park for a walk. {firststring} forgot his keys."))
          #> GAD and AB1 went to the park for a walk. GAD forgot his keys.
          #> GAD2 and AB2 went to the park for a walk. GAD2 forgot his keys.
          #> GAD3 and AB3 went to the park for a walk. GAD3 forgot his keys.
          (with(tmp, paste(firststring, "and", secondstring, "went to the park for a walk.", firststring, "forgot his keys.")))
          #> [1] "GAD and AB1 went to the park for a walk. GAD forgot his keys."  
          #> [2] "GAD2 and AB2 went to the park for a walk. GAD2 forgot his keys."
          #> [3] "GAD3 and AB3 went to the park for a walk. GAD3 forgot his keys."
          

          reprex package (v0.2.1) 于 2019-03-06 创建

          【讨论】:

            【解决方案12】:

            另一个非粘贴答案:

            x <- capture.output(cat(data, sep = ","))
            x
            [1] "GAD,AB"
            

            在哪里

             data <- c("GAD", "AB")
            

            【讨论】:

              猜你喜欢
              • 2022-11-16
              • 2013-11-05
              • 1970-01-01
              • 2011-08-29
              • 2020-08-19
              相关资源
              最近更新 更多