İki karakter dizisi nasıl birleştirilebilir?


375

İki değeri nasıl birleştirebilirim (birleştirebilir, birleştirebilir)? Örneğin:

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

Amacım "tmp" içindeki iki değeri bir dizeyle birleştirmek:

tmp_new = "GAD,AB"

Bunu hangi işlev benim için yapabilir?


Burada cevapların çoğu, @ RichardScriven'in cevap notları gibi dizeler vektörse kırılır.
smci

@ smci, gönderdiğim küçük cevap ne olacak? geliştirmek için herhangi bir öneriniz var mı?
joel.wilson

Yanıtlar:


505
paste()

gitmek için bir yoldur. Önceki posterlerin işaret ettiği gibi, macun iki şey yapabilir:

değerleri bir "dizeye" birleştirin, ör.

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

burada bağımsız değişken sepkarakter vektörlerini birleştirmek veya daraltmak için bağımsız değişkenler arasında kullanılacak karakterleri belirtir

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

burada bağımsız değişken collapse, daraltılacak vektörün elemanları arasında kullanılacak karakterleri belirtir.

Her ikisini de birleştirebilirsiniz:

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

Bu yardımcı olur umarım.


9
Dizeleri ve vektörleri veya farklı uzunluklardaki vektörleri karıştırmak paste(), benim beğenmem için biraz fazla esnek . Örneğin, paste(c('a','b'),'blah', c(1,2,3))sonuçlanır "a blah 1" "b blah 2" "a blah 3". Temel olarak, iletilen en uzun vektörle aynı uzunlukta bir dizeler vektörü oluşturur ve diğer vektörleri / dizeleri aynı uzunlukta döndürür. Orada yanlışlıkla davranış için bol yer.
naught101

1
Doğru - ancak soruyu ele alan alternatif bir yaklaşım sağlayabilir misiniz?
Rainer

1
hayır - cevabınız doğru (aynı şeyi söyleyen diğer cevapların çoğu gibi). Sadece macunun davranışının esnekliğinde olağandışı olduğunu fark ettim.
naught101

2
@ naught101 Ben R standartlarına göre olağandışı düşünmezdim. Vektör geri dönüşümü, R fonksiyonlarının ortak bir özelliğidir. Unutmayın ki 'filan' uzunluk 1'in bir vektörüdür. Geri dönüşüm özelliği, paste0("blah", 1:3)almak gibi bir şey yapmayı kolaylaştırır "blah1" "blah2" "blah3".
Dason

5
Evet, R'den şikayet etmeliyim, sadece macun değil: P. Aslında R'de tutarsızdır - data.frame()vektörler birbirinin katları değilse bunu yapmanıza izin vermez. matrix()uyarı verir, ama uyarmaz array(). Biraz sinir bozucu. Gerçekten, bazı seçenek belirlenmedikçe hepsi uyarıları tükürmek gerekir ...
naught101

85

help.search() kullanışlı bir işlevdir, ör.

> help.search("concatenate")

sizi yönlendirecektir paste().


42

İlk paste()cevap vermemek için stringr::str_c()(ve sonra toString()aşağıya) bakabiliriz . Bu soru kadar uzun sürmedi, bu yüzden de var olduğunu belirtmenin yararlı olduğunu düşünüyorum.

Gördüğünüz gibi kullanımı çok basit.

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

Dokümantasyon dosya açıklamasından bu soruna çok iyi uyuyor.

Str_c'nin nasıl çalıştığını anlamak için, bir dize matrisi oluşturduğunuzu düşünmeniz gerekir. Her girdi bağımsız değişkeni bir sütun oluşturur ve normal geri dönüşüm kuralları kullanılarak en uzun bağımsız değişkenin uzunluğuna genişletilir. Sep dizesi her sütun arasına eklenir. Daralt NULL ise, her satır tek bir dizeye daraltılır. NULL değilse, bu dize her satırın sonuna eklenir ve tüm matris tek bir dizeye daraltılır.

13.04.2016 Eklendi : İstediğiniz çıktıyla (ekstra alan) tam olarak aynı değil, ancak hiç kimse bundan bahsetmedi. toString()temel paste()olarak collapse = ", "sabit kodlanmış bir sürümüdür , böylece

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

3
Heh, bu sadece bir grup değer değil, tmp'nin bir vektör olduğu gerçeğini ele alan tek cevaptır - vektör pasteyapmaz. Diğer seçenek do.call(paste, as.list(tmp)).
naught101

35

Diğerlerinin de belirttiği gibi paste(), gitmenin yolu budur. Ancak paste(str1, str2, str3, sep=''), varsayılan olmayan ayırıcıyı her istediğinizde yazmak zorunda olmak can sıkıcı olabilir .

Hayatı daha basit hale getiren sargı işlevlerini kolayca oluşturabilirsiniz. Örneğin, kendinizi sık sık ayırıcı olmadan dizeleri birleştirirken bulursanız, şunları yapabilirsiniz:

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

veya sık sık bir vektörden ( implode()PHP gibi ) dizelere katılmak istiyorsanız :

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

Bunu yapmanıza izin verir:

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

Ayrıca, benimkiyle paste0aynı şeyi yapan implode, ancak özel ayırıcılara izin vermeyen yerleşik var . Biraz daha verimlidir paste().



28

Alternatif olarak, hedefiniz doğrudan bir dosyaya veya stdout'a çıktı almaksa, şunları kullanabilirsiniz cat:

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

4
Peki, paste4 yıl sonra, yaklaşık bir düzine pastecevap varken cevap göndermek ne anlama geliyor ?
David Arenburg

4
O zaman kendim için birden fazla cevap özetlemem yararlı oldu. Amaç oy toplamak değil, başkalarına sunulan birçok çözümü filtrelemelerine yardımcı olmaktı. Genellikle aradığım şey budur.
Megatron

22

Diğer yol:

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

Bazen paste()fonksiyondan daha yararlıdır . %ssübjektif dizelerin dahil edileceği yeri belirtir.

Bir yol oluşturmaya çalışırken bunun kullanışlı olacağını unutmayın:

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

çıktı

/this/is/a/path

R ile ilgilenen C programcıları için, sprintf "iki dizeyi birleştirmek" için tanıdık ve kullanışlıdır
subsci

Çok daha iyi imho. pastebir dizeye bir şey eklemek istiyorsanız yeterince esnek değildir.
görünen ad

20

Kendi operatörünüzü oluşturabilirsiniz:

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

Ayrıca 've' ( &) operatörünü yeniden tanımlayabilirsiniz :

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

taban çizgisi sözdizimi ile uğraşmak çirkindir, ancak paste()/paste0()yalnızca kendi kodunuzla çalışıyorsanız (neredeyse her zaman) mantıksal & andoperatörün yerini alabilir *ve mantıksal 've' yerine mantıksal değerlerin çarpımını yapabilirsiniz


@Richard Scriven mayby ​​Anlamıyorum, ama anlaşılır görünüyor, karşılaştırın: paste0(as.matrix(iris[1:4]) , as.matrix(iris[1:4]))veas.matrix(iris[1:4]) %&% as.matrix(iris[1:4])
Qbik

çok çok iyi! & birçok dilde birleştirme için standarttır, aslında R'nin varsayılan olarak olması gerektiğini düşünüyorum. şiddetle tavsiye bu şekilde
Serhii

14

Oluşturduğunuz matris, tmp göz önüne alındığında:

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

Sadece aksine, cbind kullanarak bir matris oluşturmanın bir nedeni olduğunu varsayalım:

tmp <- "GAD,AB"

3

Dizelerin sütun olduğu ve sonucun yeni bir sütun olması gerektiğini düşünün:

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

İsteğe bağlı olarak, [c("a", "b")]tüm sütunların yapıştırılması gerekiyorsa alt ayarı atlayın .

# 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 = ", ")) 

Tamam ama stringi, stringrkütüphaneler daha hızlı.
smci

2

Yapışmayan başka bir cevap:

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

Nerede

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

2

gluetidyverseçok sayıda genişletilmiş işlevsellik ile bir parçası olarak geliştirilen yeni bir işlev, veri sınıfı ve paketidir . Yapıştır, sprintf ve önceki diğer yanıtların özelliklerini birleştirir.

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

2019-03-06 tarihinde reprex paketi tarafından oluşturuldu (v0.2.1)

Evet, bu sorudaki basit örnek için aşırı kilolu, ancak birçok durum için güçlü. (bkz. https://glue.tidyverse.org/ )

Aşağıdaki pasteile karşılaştırıldığında hızlı bir örnek with. glueKod yazmak için biraz daha kolay oldu ve okunması biraz daha kolay görünüyor.

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

2019-03-06 tarihinde reprex paketi tarafından oluşturuldu (v0.2.1)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.