R: how to split a data.frame into smaller data.frames with 2 columns

Viewed 45
library(mvtnorm)
d <- 10
set.seed(1)
x <- as.data.frame(rmvnorm(n = 10, mean = 1:d, sigma = diag(d)))
split_col <- 2

I have a d x d object x. And I want to split it into d/split_col = 5 data.frames, each with split_col = 2 columns.

> x
           V1         V2       V3       V4       V5       V6       V7       V8        V9       V10
1   1.4094018  3.6888733 4.586588 3.669092 2.714764 8.497662 7.667066 8.541327  8.986600 10.510108
2   0.8356242  2.4206946 2.599753 2.629792 5.987838 7.519745 6.691259 6.746710  9.642241  9.955291
3  -0.7332184  2.0021319 2.369700 3.659031 3.843428 7.803142 6.668868 6.394487  9.197193 10.263176
4   0.0141733 -0.8889207 2.359518 4.570508 4.940277 5.901821 7.560821 6.813541 10.096777  9.994656
5   1.7073107  3.0341077 3.223480 3.121292 6.162965 3.999835 6.455209 7.744329  8.833879 11.020464
6   1.1362219  2.4071676 2.930345 3.752336 5.695551 7.146228 4.596904 8.572740  9.374724  9.574732
7   1.9510128  1.6107628 2.715669 4.857410 6.719627 6.270055 6.577816 6.810887  8.668967  9.060171
8   0.7410674  2.3943792 2.148143 6.649167 5.156012 7.130207 4.710876 8.741001  7.683755 10.919804
9   1.3981302  1.5924714 4.324259 3.298768 4.419386 4.998928 6.331821 8.945185  9.433702 11.005159
10  0.6098813  2.3763703 3.244165 2.573743 6.778429 6.134448 7.765599 8.955137  8.949434  9.694185

So I want to result to be

> results[[1]]
           V1         V2
1   1.4094018  3.6888733
2   0.8356242  2.4206946
3  -0.7332184  2.0021319
4   0.0141733 -0.8889207
5   1.7073107  3.0341077
6   1.1362219  2.4071676
7   1.9510128  1.6107628
8   0.7410674  2.3943792
9   1.3981302  1.5924714
10  0.6098813  2.3763703
> results[[2]]
         V3       V4
1  4.586588 3.669092
2  2.599753 2.629792
3  2.369700 3.659031
4  2.359518 4.570508
5  3.223480 3.121292
6  2.930345 3.752336
7  2.715669 4.857410
8  2.148143 6.649167
9  4.324259 3.298768
10 3.244165 2.573743

and so forth.

2 Answers

We can use split.default

out <- split.default(x, as.integer(gl(ncol(x), split_col, ncol(x))))

-output

out
$`1`
          V1       V2
1  0.3735462 2.183643
2  2.5117812 2.389843
3  1.9189774 2.782136
4  2.3586796 1.897212
5  0.8354764 1.746638
6  1.3981059 1.387974
7  3.4016178 1.960760
8  1.4755095 1.290054
9  0.4313313 1.864821
10 0.4574800 3.207868

$`2`
         V3       V4
1  2.164371 5.595281
2  2.378759 1.785300
3  3.074565 2.010648
4  3.387672 3.946195
5  3.696963 4.556663
6  3.341120 2.870637
7  3.689739 4.028002
8  3.610726 3.065902
9  4.178087 2.476433
10 4.160403 4.700214
...

Using lapply -

start <- (seq(d/split_col) - 1) * split_col 
lapply(start, function(i) x[i + seq(split_col)])

#[[1]]
#          V1       V2
#1  0.3735462 2.183643
#2  2.5117812 2.389843
#3  1.9189774 2.782136
#4  2.3586796 1.897212
#5  0.8354764 1.746638
#6  1.3981059 1.387974
#7  3.4016178 1.960760
#8  1.4755095 1.290054
#9  0.4313313 1.864821
#10 0.4574800 3.207868

#[[2]]
#         V3       V4
#1  2.164371 5.595281
#2  2.378759 1.785300
#3  3.074565 2.010648
#4  3.387672 3.946195
#5  3.696963 4.556663
#6  3.341120 2.870637
#7  3.689739 4.028002
#8  3.610726 3.065902
#9  4.178087 2.476433
#10 4.160403 4.700214
#...
#...
Related