0

I want to combine vectors of values, each currently saved as a row in a matrix, into single cells, with values separate by commas.

My current code creates random vectors.

For instance,

## Group 1
N <- 10

set.seed(06510)

grp1 <- t(replicate(N, sample(seq(1:4), 4, replace = FALSE)) )

The results look like

Table 1:

      [,1] [,2] [,3] [,4]
 [1,]    2    4    3    1
 [2,]    4    2    1    3
 [3,]    2    4    1    3
 [4,]    1    4    3    2
 [5,]    1    3    2    4
 [6,]    2    1    3    4
 [7,]    4    3    2    1
 [8,]    4    1    3    2
 [9,]    2    4    3    1
[10,]    1    4    2    3

But I want the results to look like:

Table 2:

        [,1] 
 [1,]  2,4,3,1
 [2,]  4,2,1,3
 [3,]  2,4,1,3
 [4,]  1,4,3,2
 [5,]  1,3,2,4
 [6,]  2,1,3,4
 [7,]  4,3,2,1
 [8,]  4,1,3,2
 [9,]  2,4,3,1
[10,]  1,4,2,3

I'm creating a randomization table and each cell represents the ordering of 4 survey questions for each survey respondent. Ultimately, I want to create multiple columns like the one above, so maintaining 4 columns for every randomization item will make for a big hard-to-read randomization table.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Dr. Beeblebrox
  • 838
  • 2
  • 13
  • 30
  • 1
    sooner or later you're going to discover that long format tables (google to see what that means) would work much better for your task – eddi Mar 28 '14 at 15:10

2 Answers2

3

Your main problem is you need to use the function I() to protect the list strucuture. Your second problem is that you need to return a list structure from replicate() which is returning a matrix (because you have a set of equal length vectors). Set simplify = FALSE and note where the transpose operation t occurs....

grp1 <- replicate(N, t( sample(seq(1:4), 4, replace = FALSE ) ) , simplify = FALSE )

as.data.frame( I(grp1) )
#      I(grp1)
#1  2, 4, 3, 1
#2  4, 2, 1, 3
#3  2, 4, 1, 3
#4  1, 4, 3, 2
#5  1, 3, 2, 4
#6  2, 1, 3, 4
#7  4, 3, 2, 1
#8  4, 1, 3, 2
#9  2, 4, 3, 1
#10 1, 4, 2, 3

# And just to check...
sapply( as.data.frame( I(grp1) ) , mode )
I(grp1) 
 "list" 

However, I don't know why this is more useful to you than a plain old data.frame or probably even better for your use-case, a list of matrices.

Simon O'Hanlon
  • 58,647
  • 14
  • 142
  • 184
  • +1. If the number of values is small (here, 4) but the number of groups is large (here, 10, but let's imagine 10K groups), it might be better to generate all permutations first (with a function like [this one](http://stackoverflow.com/a/20199902/1270695), for example) and then sample the rows instead of repeatedly calling `sample`. However, if the number of values is large, generating the permutations might be slower than just repeatedly calling sample. – A5C1D2H2I1M1N2O1R2T1 Mar 28 '14 at 17:09
0

Whatever you do, you will end up with characters, I hope you are not surprised by that.

apply(grp1,1,paste,collapse=",")

gives you a vector result. You can turn that into a matrix like this:

matrix(apply(grp1,1,paste,collapse=","),ncol=1)

See ?apply. apply() is enormously useful.

Stephan Kolassa
  • 7,953
  • 2
  • 28
  • 48
  • If this is what they are looking for, in the long run, the following would be a faster alternative: `do.call(paste, c(data.frame(grp1), sep = ","))` – A5C1D2H2I1M1N2O1R2T1 Mar 28 '14 at 13:34