Reputation: 1881
I'm trying to write a loop within a loop in R, but it seems only the inner loop is working:
test <- rbind(c(1:30), c(31:60), c(61:90), c(91:120))
Here's what I've been written:
b<- data.frame()
n<-1
i<-1
c<- data.frame()
while(i<=4){
while(n<=10) {
a<-cbind(test[i, 3*n-2], test[i, 3*n-1], test[i,3*n])
b<-rbind(b,a); n<-n+1
} ; i<-i+1; c<-cbind(c,b)
}
Basically what I'm trying to do is to group each line by three columns and transform it into multiple lines, and then do it to every line and bind these columns.
My desired output would look like:
1 2 3 31 32 33 61 62 63 81 82 83
4 5 6 34 35 36 64 65 66 84 85 86
7 8 9 37 38 39 67 68 69 ......
10 11 12 40 41 42 ......
13 14 15 43 45 46
16 17 18 ......
19 20 21
22 23 24
25 26 27
28 29 30 58 59 60 78 79 80 118 119 120
However what I have written only work for the first line, apparently the outer loop doesn't work. What's wrong with it please?
edit: Here's what I further tried in response to the for loop:
b<- data.frame()
c<- data.frame()
for(i in seq(from = 1, to = 4, by =1)){
for( n in seq(from=1, to=10, by=1)) {
a <- cbind(test[i, 3*n-2], test[i, 3*n-1], test[i,3*n])
b <- rbind(b,a)
}
c <- cbind(c,b)
}
But I still could not make it work. what's wrong with it?
Upvotes: 0
Views: 4618
Reputation: 59970
This might make your life a bit easier...
out <- lapply( data.frame( t(test) ) , matrix , ncol = 3 , byrow = TRUE )
res <- do.call( cbind , out )
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,] 1 2 3 31 32 33 61 62 63 91 92 93
[2,] 4 5 6 34 35 36 64 65 66 94 95 96
[3,] 7 8 9 37 38 39 67 68 69 97 98 99
[4,] 10 11 12 40 41 42 70 71 72 100 101 102
[5,] 13 14 15 43 44 45 73 74 75 103 104 105
[6,] 16 17 18 46 47 48 76 77 78 106 107 108
[7,] 19 20 21 49 50 51 79 80 81 109 110 111
[8,] 22 23 24 52 53 54 82 83 84 112 113 114
[9,] 25 26 27 55 56 57 85 86 87 115 116 117
[10,] 28 29 30 58 59 60 88 89 90 118 119 120
Possibly even slightly easier would be to do...
do.call( cbind , lapply( 1:4 , function(x) matrix( test[x,] , ncol = 3 , byrow = F ) ) )
If you insist on using a for
loop this is probably the easiest way...
out <- numeric()
for( i in 1:4 ){
tmp <- matrix( test[ i , ] , ncol = 3 , byrow = TRUE )
out <- cbind( out , tmp )
}
The problem stemmed from your use of out <- data.frame
to initialise the result data structure. It meant you were trying to cbind
a data.frame
with no rows to one with 10 rows. Not possible (although intuitively being able to cbind
an empty vector with a 10 row matrix
should probably fail too but it doesnt!).
Upvotes: 4