Q:

R - How to fill a matrix by columns

I am trying to fill the columns of a matrix with the subsets of an built-in data frame. The resulting matrix should have dimensions 16 by 11 and each subset is 16 integers long.
I have written the following for loop:
A <- unique(DNase$Run)
z <- matrix(data =NA, ncol=11, nrow =16)
for (i in A) {
   z[,i] <- subset(DNase$density, DNase$Run==i)
}

and I obtain the following error:
Error in [<-(*tmp*, , i, value = c(0.017, 0.018, 0.121, 0.124, 0.206,  : 
  no 'dimnames' attribute for array
Could anyone kindly explain where the confusion comes from? 
Many thanks in advance!

A:

Cheap Solution
Since the DNase data.frame is already ordered by the Run factor, we can actually form the desired output matrix with a simple call to matrix():
matrix(DNase$density,16);
##        [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10] [,11]
##  [1,] 0.017 0.045 0.070 0.011 0.035 0.086 0.094 0.054 0.032 0.052 0.047
##  [2,] 0.018 0.050 0.068 0.016 0.035 0.103 0.092 0.054 0.043 0.094 0.057
##  [3,] 0.121 0.137 0.173 0.118 0.132 0.191 0.182 0.152 0.142 0.164 0.159
##  [4,] 0.124 0.123 0.165 0.108 0.135 0.189 0.182 0.148 0.155 0.166 0.155
##  [5,] 0.206 0.225 0.277 0.200 0.224 0.272 0.282 0.226 0.239 0.259 0.246
##  [6,] 0.215 0.207 0.248 0.206 0.220 0.277 0.273 0.222 0.242 0.256 0.252
##  [7,] 0.377 0.401 0.434 0.364 0.385 0.440 0.444 0.392 0.420 0.439 0.427
##  [8,] 0.374 0.383 0.426 0.360 0.390 0.426 0.439 0.383 0.395 0.439 0.411
##  [9,] 0.614 0.672 0.703 0.620 0.658 0.686 0.686 0.658 0.624 0.690 0.704
## [10,] 0.609 0.681 0.689 0.640 0.647 0.676 0.668 0.644 0.705 0.701 0.684
## [11,] 1.019 1.116 1.067 0.979 1.060 1.062 1.052 1.043 1.046 1.042 0.994
## [12,] 1.001 1.078 1.077 0.973 1.031 1.072 1.035 1.002 1.026 1.075 0.980
## [13,] 1.334 1.554 1.629 1.424 1.425 1.424 1.409 1.466 1.398 1.340 1.421
## [14,] 1.364 1.526 1.479 1.399 1.409 1.459 1.392 1.381 1.405 1.406 1.385
## [15,] 1.730 1.932 2.003 1.740 1.750 1.768 1.759 1.743 1.693 1.699 1.715
## [16,] 1.710 1.914 1.884 1.732 1.738 1.806 1.739 1.724 1.729 1.708 1.721

This of course depends on the aforementioned ordering, which can be verified with a call to rle():
do.call(data.frame,rle(levels(DNase$Run)[DNase$Run]));
##    lengths values
## 1       16      1
## 2       16      2
## 3       16      3
## 4       16      4
## 5       16      5
## 6       16      6
## 7       16      7
## 8       16      8
## 9       16      9
## 10      16     10
## 11      16     11

Robust Solution
If we don't want to depend on that ordering, we can use reshape() as follows, and we get a nice bonus of column names, if you want that:
reshape(cbind(DNase[c('Run','density')],id=ave(c(DNase$Run),DNase$Run,FUN=seq_along)),dir='w',timevar='Run')[-1];
##    density.1 density.2 density.3 density.4 density.5 density.6 density.7 density.8 density.9 density.10 density.11
## 1      0.017     0.045     0.070     0.011     0.035     0.086     0.094     0.054     0.032      0.052      0.047
## 2      0.018     0.050     0.068     0.016     0.035     0.103     0.092     0.054     0.043      0.094      0.057
## 3      0.121     0.137     0.173     0.118     0.132     0.191     0.182     0.152     0.142      0.164      0.159
## 4      0.124     0.123     0.165     0.108     0.135     0.189     0.182     0.148     0.155      0.166      0.155
## 5      0.206     0.225     0.277     0.200     0.224     0.272     0.282     0.226     0.239      0.259      0.246
## 6      0.215     0.207     0.248     0.206     0.220     0.277     0.273     0.222     0.242      0.256      0.252
## 7      0.377     0.401     0.434     0.364     0.385     0.440     0.444     0.392     0.420      0.439      0.427
## 8      0.374     0.383     0.426     0.360     0.390     0.426     0.439     0.383     0.395      0.439      0.411
## 9      0.614     0.672     0.703     0.620     0.658     0.686     0.686     0.658     0.624      0.690      0.704
## 10     0.609     0.681     0.689     0.640     0.647     0.676     0.668     0.644     0.705      0.701      0.684
## 11     1.019     1.116     1.067     0.979     1.060     1.062     1.052     1.043     1.046      1.042      0.994
## 12     1.001     1.078     1.077     0.973     1.031     1.072     1.035     1.002     1.026      1.075      0.980
## 13     1.334     1.554     1.629     1.424     1.425     1.424     1.409     1.466     1.398      1.340      1.421
## 14     1.364     1.526     1.479     1.399     1.409     1.459     1.392     1.381     1.405      1.406      1.385
## 15     1.730     1.932     2.003     1.740     1.750     1.768     1.759     1.743     1.693      1.699      1.715
## 16     1.710     1.914     1.884     1.732     1.738     1.806     1.739     1.724     1.729      1.708      1.721

Note that technically the above object is a data.frame, but you can easily coerce to matrix with as.matrix().
Explanation of Your Error
The reason why your code is failing is as follows. First, notice that the DNase$Run vector is actually an ordered factor:
class(DNase$Run);
## [1] "ordered" "factor"

Your A variable will therefore also be an ordered factor, just with the unique values from DNase$Run.
Now, when you use a for-loop to iterate over a factor (ordered or otherwise), it uses the levels (character strings) as the iteration value (as opposed to the integer enumeration values that are stored internally). Demo:
for (i in factor(letters[1:5])) print(i);
## [1] "a"
## [1] "b"
## [1] "c"
## [1] "d"
## [1] "e"

Thus, your i loop variable is being assigned to the levels character strings of DNase$Run. And, since your z matrix has no dimnames, trying to index its columns with a character string is failing with the error message "no 'dimnames' attribute for array".

