I am trying to generate a matrix where each element is a vector of length 2 and then fill the vectors automatically. What I have so far is:

```
dat <- matrix(list(vector("numeric",2)),3,3)
dat
## [,1] [,2] [,3]
## [1,] Numeric,2 Numeric,2 Numeric,2
## [2,] Numeric,2 Numeric,2 Numeric,2
## [3,] Numeric,2 Numeric,2 Numeric,2
```

I want to fill this empty matrix so that it looks something like this:

```
[[,1]] [[,2]] [[,3]]
[[1,]] [1] 1 1 [1] 1 2 [1] 1 3
[[2,]] [1] 2 1 [1] 2 2 [1] 2 3
[[3,]] [1] 3 1 [1] 3 2 [1] 3 3
```

I can subset and replace each element manually with the code `dat[[1,1]] <- c(1,1)`

and I can subset all the first vector elements of `dat`

with the code `sapply(dat,"[", 1)`

, but I can't then replace these vector elements with the desired values, e.g. `sapply(dat,"[", 1) <- rep(1:3,3)`

(returns `could not find function "sapply<-"`

error).

answered 1 year ago r2evans #1

Might I suggest you use a 3-D array instead?

```
ary <- array(1:18, dim=c(3,3,2))
ary
# , , 1
# [,1] [,2] [,3]
# [1,] 1 4 7
# [2,] 2 5 8
# [3,] 3 6 9
# , , 2
# [,1] [,2] [,3]
# [1,] 10 13 16
# [2,] 11 14 17
# [3,] 12 15 18
```

Reassignment of a single "pair". Note the trailing comma, similar to how `mtcars[1,]`

returns all columns from the first row.

```
ary[1,1,] <- c(1, 1)
ary
# , , 1
# [,1] [,2] [,3]
# [1,] 1 4 7
# [2,] 2 5 8
# [3,] 3 6 9
# , , 2
# [,1] [,2] [,3]
# [1,] 1 13 16
# [2,] 11 14 17
# [3,] 12 15 18
```

To replace all first-values:

```
ary[,,1] <- rep(1:3, 3)
ary
# , , 1
# [,1] [,2] [,3]
# [1,] 1 1 1
# [2,] 2 2 2
# [3,] 3 3 3
# , , 2
# [,1] [,2] [,3]
# [1,] 1 13 16
# [2,] 11 14 17
# [3,] 12 15 18
```

In order to apply something over the matrix of paired values, you can use `apply(ary, 1:2, ...)`

, such as:

```
plot(NA, xlim=c(1,3), ylim=c(1,18))
apply(ary, c(1,2), function(pts) points(pts[1], pts[2]))
```

When you look at the `MARGIN`

argument (`c(1,2)`

here) of `apply`

, it is saying "apply a function for each row,column 'set' of the data". When looking at a simple 2-D matrix, a margin of `c(1,2)`

iterates the function over each individual value. In a 3-D array, it applies the function over each "pipe" of the matrix.

That `apply`

call is equivalent to this sequence of function calls:

```
points(1, 1)
points(2, 11)
points(3, 12)
points(1, 13)
points(2, 14)
points(3, 15)
points(1, 16)
points(2, 17)
points(3, 18)
```

(This example could easily be accomplished with `plot(ary[,,1], ary[,,2])`

, but that doesn't necessarily answer your need for a function that accepts the pair as a single argument. Similarly with `mapply(points, ary[,,1], ary[,,2])`

.)

If your consuming function takes a *vector* of values, then perhaps this will work:

```
apply(ary, c(1,2), yourfunc)
```