如何将两个字符串串联在一起?


375

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

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

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

tmp_new = "GAD,AB"

哪个功能可以为我执行此操作?


如@RichardScriven的回答所述,如果字符串是向量,则此处的大多数答案都会中断。
smci

@smci我发布的小答案怎么办?有什么建议可以改善吗?
joel.wilson

Answers:


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

希望这可以帮助。


9
混合字符串和向量或不同长度的向量paste()对于我来说太灵活了。例如,paste(c('a','b'),'blah', c(1,2,3))结果为"a blah 1" "b blah 2" "a blah 3"。基本上,它创建一个字符串矢量,该字符串的长度与传入的最长矢量相同,并将其他矢量/字符串循环到相同的长度。那里有很多发生意外行为的空间。
naught101

1
是的-但是您能提供解决这个问题的替代方法吗?
Rainer

1
否-您的答案是正确的(其他大多数回答相同的答案也是如此)。我只是在指出粘贴的行为在灵活性方面是不同寻常的。
naught101

2
@ naught101从R的标准来看,我不会认为这很不寻常。向量循环是R函数的共同属性。请记住,“ blah”是长度为1的向量。回收属性使执行诸如paste0("blah", 1:3)get的操作变得容易"blah1" "blah2" "blah3"
戴森

5
是的,我应该抱怨R,而不仅仅是粘贴:P。实际上在R上不一致- data.frame()如果向量不是彼此的倍数,则不允许您这样做。matrix()发出警告,但array()不发出警告。有点烦人。的确,除非设置了某些选项,否则他们都应该发出警告...
naught101

85

help.search() 是一个方便的功能,例如

> help.search("concatenate")

会带你去paste()


42

对于第一个不paste()回答的问题,我们可以看一下stringr::str_c()(然后再看toString()下面)。这个问题还没有出现很久,所以我认为提到它也存在很有用。

如您所见,它非常易于使用。

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

从其文档文件描述中可以很好地解决此问题。

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

添加了4/13/2016:它与所需的输出(多余的空间)不完全相同,但是也没有人提及它。 toString()基本上是paste()带有collapse = ", "硬编码的版本,因此您可以

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

3
呵呵,这是解决tmp是向量,而不仅仅是一堆值的唯一答案- paste不做向量。另一种选择是do.call(paste, as.list(tmp))
naught101 '16

35

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

您可以非常轻松地创建包装函数,使生活变得更加简单。例如,如果您发现自己实际上经常串联不带分隔符的字符串,则可以执行以下操作:

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

或者,如果您经常想从向量(如implode()PHP)中加入字符串:

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,其功能与my相同implode,但不允许自定义分隔符。效率比稍高paste()



28

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

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

4
那么,paste当四年后已经有大约十二个paste答案时,发布答案又有什么意义呢?
David Arenburg

4
当时,我发现为自己总结多个答案很有帮助。目的不是收集选票,而是帮助其他人筛选提供的许多解决方案。通常这就是我想要的。
威震天

22

另一种方式:

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对于“连接两个字符串”很熟悉并且很有用
subsci

更好的恕我直言。paste如果要在字符串后附加内容,则不够灵活。
displayname

20

您可以创建自己的运算符:

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

您还可以重新定义'and'(&)运算符:

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

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


@Richard斯克里芬mayby我不明白,但它看起来非常简单,比较:paste0(as.matrix(iris[1:4]) , as.matrix(iris[1:4]))as.matrix(iris[1:4]) %&% as.matrix(iris[1:4])
Qbik

非常非常棒!&是许多语言中串联的标准,我实际上认为R默认情况下应该具有它。强烈推荐这种方式
Serhii

14

给定您创建的矩阵tmp:

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

我认为有一些原因使您使用cbind创建矩阵,而不是简单地做到这一点:

tmp <- "GAD,AB"

3

考虑字符串为列且结果应为新列的情况:

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库更快。
smci

2

另一个非粘贴答案:

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

哪里

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

2

glue是作为的一部分开发的新功能,数据类和程序包,具有tidyverse许多扩展功能。它结合了粘贴,sprintf和先前其他答案中的功能。

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

reprex软件包(v0.2.1)创建于2019-03-06

是的,对于这个问题中的简单示例来说,这是过大的选择,但在许多情况下却很有效。(请参阅https://glue.tidyverse.org/

快速示例相比 pastewith下面。该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软件包(v0.2.1)创建于2019-03-06

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.