Another option is to convert to data.frame
and use do.call
with paste
matrix(do.call(paste0, as.data.frame(m1)))
# [,1]
#[1,] "acegi"
#[2,] "bdfhj"
NOTE: It is faster than looping through each row.
Benchmarks
set.seed(24)
m2 <- matrix(sample(letters, 1e7*4, replace=TRUE), ncol=4)
system.time(matrix(apply(m2, 1, paste, collapse="")))
# user system elapsed
# 75.81 0.27 76.44
system.time(matrix(do.call(paste0, as.data.frame(m2))))
# user system elapsed
# 9.62 0.14 9.76
Using @Frank's variation
system.time(matrix(do.call(paste0, split(m2, col(m2)))))
# user system elapsed
# 9.54 0.19 9.75
As @PierreLafortune wanted to check with a dataset with more number of columns,
set.seed(49)
m2 <- matrix(sample(letters, 1e6*10, replace=TRUE), ncol=10)
system.time(matrix(apply(m2, 1, paste, collapse="")))
# user system elapsed
# 8.90 0.00 8.89
system.time(matrix(do.call(paste0, as.data.frame(m2))))
# user system elapsed
# 1.92 0.00 1.92
If the number of rows and columns are same, say 5000 x 5000, then
set.seed(37)
m2 <- matrix(sample(letters, 5000*5000, replace=TRUE), ncol=1000)
system.time(matrix(apply(m2, 1, paste, collapse="")))
# user system elapsed
# 5.42 0.00 5.42
system.time(matrix(do.call(paste0, as.data.frame(m2))))
# user system elapsed
# 7.42 0.00 7.43
system.time({n = nrow(m2)
do.call(paste0, lapply(seq_len(ncol(m2)),
function(j) m2[seq(to=j*n, length.out=n)]))})
# user system elapsed
# 6.19 0.00 6.20
the apply
method is slightly faster, but I assume that there will be more rows than columns in the OP's dataset.