3

I want to create 27 matrix with 2 columns and a variable number of rows. I could just write 27 lines of code, like this:

 x1 = cbind(rep(1,34), rnorm(34))

 x2 = cbind(rep(1,36), rnorm(36))

....

x27 = cbind(rep(1,k), rnorm(k))

But it must have a better way to do that. I thought of a loop, something like this:

aux = c(34, 36, ..., k) # auxiliar variable with number of rows for each matrix

for (i in 1:27) paste("x",i, sep="") =  cbind(rep(1,aux[i]), rnorm(aux[i]))

However, it doesn't work. I feel like this is a simple task, but I am out of ideas.

Any help?

ps.: I thought of an array, but I wasn't able to use it. Maybe a list can do the job, I don't know.

3
  • It semmns to be important to me to creat 27 R objects (x1, x2, x3,..., x27) Commented Feb 4, 2011 at 0:10
  • look for @Joshua Ulrich's answer as I feel I might have misunderstood your question. If you need distinct matrices and not concatenated to a list, than the green check mark should go to him. Commented Feb 4, 2011 at 0:34
  • Both solutions will work. Thanks everybody and I marked your (@daroczig) answer because it worked for me. Commented Feb 5, 2011 at 20:32

4 Answers 4

7

You need assign:

for (i in 1:27) {
  assign(paste("x",i,sep=""), cbind(rep(1,aux[i]), rnorm(aux[i])))
}

This will create 27 matrix objects in your global environment.

Sign up to request clarification or add additional context in comments.

Comments

3

If you need different number of rows then you definitely need to use a list. See the example below:

First, declaring your aux variable which holds the number of rows to generate:

aux <- 50:77

And let your loop spin:

x <- vector("list",27) 
for (i in 1:27) {
    x[[i]] <- cbind(rep(1,aux[i]), rnorm(aux[i]))
}

Which will give back the list of your data frames. See e.g. str(x) for the list and str(x[[1]]) for the first matrixe's structure. The latter would return:

 num [1:50, 1:2] 1 1 1 1 1 1 1 1 1 1 ...

And you are right: it could be written a lot nicer than this proposal, look for lapply and so, but others will help you out with that tricky part :)


After editing: added lapply example

Try the code below if you are familiar with the above loop (and of course look for ?lapply):

aux <- 50:77
fun <- function(x) cbind(rep(1,x), rnorm(x))
x <- lapply(aux, fun)

6 Comments

But don't you have to create x first? something like x <- list() or x <- vector()? I my computer it didn't found the object x.
Yep, we need to create x first . Thanks very much. I used simply x <- list()
@Manoel Galdino: yes, sorry for this mistake! I have edited my answer and added the extra line, and also added an example with lapply to make the solution neater in exchange :)
Preallocate! Define x <- vector("list",27) before the loop then set each element of x inside the loop. This is much more efficient than expanding the list for each iteration.
@Joshua Ulrich: true, thank you for pointing out - that is really useful. I have edited my answer to make it nicer. And I have just (after reading your answer) realized that I might had misunderstood the question also :(
|
2

If you have nothing against lists, here's another shot at your question:

aux <- 30:40
manoel <- sapply(aux, function(x) {
            matrix(NA, ncol = 2, nrow = x)
        }, simplify = FALSE)

> str(manoel)
List of 11
 $ : logi [1:30, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:31, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:32, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:33, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:34, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:35, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:36, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:37, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:38, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:39, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:40, 1:2] NA NA NA NA NA NA ...

Comments

1

The code below shows how I used Joshua Ulrich's approach to create slightly more complex matrices. Hopefully this answer is helpful is showing some of the flexibility possible in creating objects. If not, I can delete my answer.

I suspect this approach can be modified easily to create matrices that differ in size, for example, by setting nrow or ncol equal to a variable and using rep(q, z) with some variable z to duplicate elements in the vector inside the matrix or rbind statement:

p1.c1 <- 0.10
p2.c1 <- 0.20
p3.c1 <- 0.30
p4.c1 <- 0.40

s1.c1  <- matrix(c(p1.c1, p1.c1, (1 - p1.c1),
                   p1.c1, p1.c1, (1 - p1.c1),
                       0,     0,          1), nrow=3, ncol=3, byrow = TRUE)
s2.c1  <- matrix(c(p2.c1, p2.c1, (1 - p2.c1),
                   p2.c1, p2.c1, (1 - p2.c1),
                       0,     0,          1), nrow=3, ncol=3, byrow = TRUE)
s3.c1  <- matrix(c(p3.c1, p3.c1, (1 - p3.c1),
                   p3.c1, p3.c1, (1 - p3.c1),
                       0,     0,          1), nrow=3, ncol=3, byrow = TRUE)
s4.c1  <- matrix(c(p4.c1, p4.c1, (1 - p4.c1),
                   p4.c1, p4.c1, (1 - p4.c1),
                       0,     0,          1), nrow=3, ncol=3, byrow = TRUE)

n <- 5

p.c1 <- c(p1.c1, p2.c1, p3.c1, p4.c1)

for (i in 1: (n - 1)) {
  assign(paste('xs', i, '.c1', sep=""), matrix(c(p.c1[i], p.c1[i], (1-p.c1[i]),
                                                 p.c1[i], p.c1[i], (1-p.c1[i]),
                                                       0,       0,         1 ), nrow=3, ncol=3, byrow = TRUE))
}
identical(xs1.c1, s1.c1)
identical(xs2.c1, s2.c1)
identical(xs3.c1, s3.c1)
identical(xs4.c1, s4.c1)

for (i in 1: (n - 1)) {
  assign(paste('ys', i, '.c1', sep=""), rbind(c(p.c1[i], p.c1[i], (1-p.c1[i])),
                                              c(p.c1[i], p.c1[i], (1-p.c1[i])),
                                                    c(0,       0,          1)))

}
identical(ys1.c1, s1.c1)
identical(ys2.c1, s2.c1)
identical(ys3.c1, s3.c1)
identical(ys4.c1, s4.c1)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.