Bagaimana dua string bisa digabungkan?

375

Bagaimana saya bisa menggabungkan (menggabungkan, menggabungkan) dua nilai? Misalnya saya punya:

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

Tujuan saya adalah menggabungkan dua nilai dalam "tmp" ke satu string:

tmp_new = "GAD,AB"

Fungsi mana yang bisa melakukan ini untuk saya?

Hans
sumber
Sebagian besar jawaban di sini terputus jika stringnya adalah vektor, seperti yang dicatat oleh @ RichardScriven.
smci
@smci bagaimana dengan jawaban kecil yang saya posting? ada saran untuk memperbaikinya?
joel.wilson

Jawaban:

505
paste()

adalah cara untuk pergi. Seperti yang ditunjukkan poster sebelumnya, tempel dapat melakukan dua hal:

menggabungkan nilai menjadi satu "string", mis

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

di mana argumen sepmenentukan karakter yang akan digunakan antara argumen untuk menyatukan, atau menciutkan vektor karakter

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

di mana argumen collapsemenentukan karakter yang akan digunakan di antara elemen-elemen vektor yang akan diciutkan.

Anda bahkan dapat menggabungkan keduanya:

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

Semoga ini membantu.

Rainer
sumber
9
Menggabungkan string dan vektor atau vektor dengan panjang yang berbeda agak terlalu fleksibel paste()untuk selera saya. Misalnya, paste(c('a','b'),'blah', c(1,2,3))hasil dalam "a blah 1" "b blah 2" "a blah 3". Pada dasarnya, ia menciptakan vektor string dengan panjang yang sama dengan vektor terpanjang yang dilewati, dan loop vektor / string lainnya ke panjang yang sama. Banyak ruang untuk perilaku tidak disengaja di sana.
naught101
1
Benar - tetapi dapatkah Anda memberikan pendekatan alternatif yang menjawab pertanyaan?
Rainer
1
tidak - jawaban Anda benar (seperti juga sebagian besar jawaban lain yang mengatakan hal yang sama). Saya hanya mencatat bahwa perilaku pasta tidak biasa dalam fleksibilitasnya.
nucky101
2
@ naught101 Saya tidak akan menganggapnya tidak biasa menurut standar R. Daur ulang vektor adalah properti umum fungsi R. Ingatlah bahwa 'bla' adalah vektor dengan panjang 1. Properti daur ulang membuatnya mudah untuk melakukan sesuatu seperti paste0("blah", 1:3)mendapatkan "blah1" "blah2" "blah3".
Dason
5
Ya, saya harus mengeluh tentang R, bukan hanya menempel: P. Ini sebenarnya tidak konsisten di R - data.frame()tidak membiarkan Anda melakukannya jika vektor bukan kelipatan satu sama lain. matrix()memuntahkan peringatan, tetapi array()tidak. Agak menyebalkan. Sungguh, mereka semua harus mengeluarkan peringatan kecuali beberapa opsi ditetapkan ...
non't101
85

help.search() adalah fungsi praktis, mis

> help.search("concatenate")

akan membawa Anda ke paste().

lebih lanjut
sumber
42

Untuk paste()jawaban pertama , kita bisa melihat stringr::str_c()(dan kemudiantoString() bawah). Belum ada selama pertanyaan ini, jadi saya pikir itu berguna untuk menyebutkan bahwa itu juga ada.

Sangat mudah digunakan, seperti yang Anda lihat.

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

Dari deskripsi file dokumentasinya, ini cocok dengan masalah ini.

Untuk memahami bagaimana str_c bekerja, Anda perlu membayangkan bahwa Anda sedang membangun matriks string. Setiap argumen input membentuk kolom, dan diperluas ke panjang argumen terpanjang, menggunakan aturan recyling yang biasa. String sep dimasukkan di antara setiap kolom. Jika runtuh adalah NULL, setiap baris diciutkan menjadi satu string. Jika non-NULL string itu dimasukkan pada akhir setiap baris, dan seluruh matriks diciutkan menjadi satu string.

Ditambahkan 4/13/2016 : Ini tidak persis sama dengan output yang Anda inginkan (ruang ekstra), tetapi tidak ada yang menyebutkannya juga. toString()pada dasarnya adalah versi paste()dengan collapse = ", "hard-coded, jadi Anda bisa melakukannya

toString(tmp)
# [1] "GAD, AB"
Scriven Kaya
sumber
3
Heh, ini adalah satu-satunya jawaban yang membahas fakta bahwa tmp adalah vektor, dan bukan hanya sekelompok nilai - pastetidak melakukan vektor. Pilihan lainnya adalah do.call(paste, as.list(tmp)).
naught101
35

Seperti yang telah ditunjukkan orang lain, paste()adalah jalan yang harus ditempuh. Tapi itu bisa menjengkelkan harus mengetik paste(str1, str2, str3, sep='')setiap kali Anda ingin pemisah non-standar.

Anda dapat dengan mudah membuat fungsi pembungkus yang membuat hidup lebih sederhana. Misalnya, jika Anda mendapati diri Anda merangkai senar tanpa pemisah, Anda dapat:

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

atau jika Anda sering ingin menggabungkan string dari vektor (seperti implode()dari PHP):

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

Memungkinkan Anda melakukan ini:

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

Juga, ada built-in paste0, yang melakukan hal yang sama seperti saya implode, tetapi tanpa mengizinkan pemisah kustom. Ini sedikit lebih efisien daripada paste().

tidak ada apa-apa101
sumber
28

Atau, jika tujuan Anda adalah untuk menampilkan langsung ke file atau stdout, Anda dapat menggunakan cat:

cat(s1, s2, sep=", ")
Megatron
sumber
4
Jadi apa gunanya memposting pastejawaban 4 tahun kemudian ketika sudah ada sekitar selusin pastejawaban?
David Arenburg
4
Pada saat itu saya merasa terbantu untuk merangkum beberapa jawaban untuk diri saya sendiri. Tujuannya bukan untuk mengumpulkan suara tetapi untuk membantu orang lain menyaring melalui banyak solusi yang ditawarkan. Seringkali itulah yang saya cari.
Megatron
22

Cara lain:

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

Kadang-kadang berguna daripada paste()fungsi. %smenunjukkan tempat di mana string subjektif akan dimasukkan.

Perhatikan bahwa ini akan berguna saat Anda mencoba membangun jalur:

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

keluaran

/this/is/a/path
Suat Atan PhD
sumber
untuk programmer C yang berurusan dengan R, sprintf akrab dan berguna untuk "menggabungkan dua string"
subsci
Imho yang jauh lebih baik. pastetidak cukup fleksibel jika Anda ingin menambahkan sesuatu ke string.
displayname
20

Anda dapat membuat operator Anda sendiri:

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

Anda juga dapat mendefinisikan ulang &operator 'dan' ( ):

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

mengacaukan sintaksis dasar jelek, tetapi begitu juga menggunakan paste()/paste0()jika Anda hanya bekerja dengan kode Anda sendiri, Anda dapat (hampir selalu) mengganti & andoperator logis dengan *dan melakukan penggandaan nilai-nilai logis daripada menggunakan logis 'dan &'

Qbik
sumber
@ Richard Scriven mayby ​​saya tidak mengerti, tapi sepertinya langsung, bandingkan: paste0(as.matrix(iris[1:4]) , as.matrix(iris[1:4]))danas.matrix(iris[1:4]) %&% as.matrix(iris[1:4])
Qbik
sangat sangat baik! & standar untuk rangkaian dalam banyak bahasa, saya pikir R seharusnya sudah memilikinya secara default. sangat merekomendasikan cara ini
Serhii
14

Dengan matriks, tmp, yang Anda buat:

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

Saya berasumsi ada beberapa alasan mengapa Anda membuat matriks menggunakan cbind, bukan hanya:

tmp <- "GAD,AB"
neilfws
sumber
3

Pertimbangkan kasus di mana string adalah kolom dan hasilnya harus berupa kolom baru:

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

Secara opsional, lewati [c("a", "b")]subset jika semua kolom perlu ditempel.

# 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 = ", ")) 
joel.wilson
sumber
OK tapi stringi, stringrperpustakaan lebih cepat.
smci
2

Jawaban tanpa tempel lainnya:

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

Dimana

 data <- c("GAD", "AB")
sindri_baldur
sumber
2

glueadalah fungsi baru, kelas data, dan paket yang telah dikembangkan sebagai bagian dari tidyverse, dengan banyak fungsi tambahan. Ini menggabungkan fitur dari tempel, sprintf, dan jawaban lain sebelumnya.

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

Dibuat pada 2019-03-06 oleh paket reprex (v0.2.1)

Ya, itu berlebihan untuk contoh sederhana dalam pertanyaan ini, tetapi kuat untuk banyak situasi. (lihat https://glue.tidyverse.org/ )

Contoh cepat dibandingkan pastedengan di withbawah ini. The gluekode adalah sedikit lebih mudah untuk mengetik dan tampak agak lebih mudah dibaca.

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

Dibuat pada 2019-03-06 oleh paket reprex (v0.2.1)

Arthur Yip
sumber