Bernard
Bernard

Reputation: 67

Split a data frame by column using a list of vectors

I want to split this data frame df by column using a list of vectors ind as the column indices.

> df
    1  2  3  4  5  6  7  8  9  10
1   1 11 21 31 41 51 61 71 81  91
2   2 12 22 32 42 52 62 72 82  92
3   3 13 23 33 43 53 63 73 83  93
4   4 14 24 34 44 54 64 74 84  94
5   5 15 25 35 45 55 65 75 85  95
6   6 16 26 36 46 56 66 76 86  96
7   7 17 27 37 47 57 67 77 87  97
8   8 18 28 38 48 58 68 78 88  98
9   9 19 29 39 49 59 69 79 89  99
10 10 20 30 40 50 60 70 80 90 100

The combined length of the vectors are equal to the number of columns in the data frame.

> ind 
[[1]]
[1] 1 4 9

[[2]]
[1] 2 5 10 7 3

[[3]]
[1]  8 6

The desired result should look like this:

$`1`
    1  4  9
1   1 31 81
2   2 32 82
3   3 33 83
4   4 34 84
5   5 35 85
6   6 36 86
7   7 37 87
8   8 38 88
9   9 39 89
10 10 40 90

$`2`
    2  5  10  7  3
1  11 41  91 61 21
2  12 42  92 62 22
3  13 43  93 63 23
4  14 44  94 64 24
5  15 45  95 65 25
6  16 46  96 66 26
7  17 47  97 67 27
8  18 48  98 68 28
9  19 49  99 69 29
10 20 50 100 70 30

$`3`
    8  6
1  71 51
2  72 52
3  73 53
4  74 54
5  75 55
6  76 56
7  77 57
8  78 58
9  79 59
10 80 60

Effectively the code generates sub matrices as data frames from the data frame df based on the vectors in the list ind

I have tried using split.defult without achieving the desired result.

split.default(V, rep(seq_along(ind), lengths(ind)))

Upvotes: 0

Views: 146

Answers (3)

tmfmnk
tmfmnk

Reputation: 40171

One purrr option could be:

map(.x = ind, ~ df[, .x])

[[1]]
  X1 X4 X9
1  1 31 81
2  2 32 82
3  3 33 83

[[2]]
  X2 X5 X10 X7 X3
1 11 41  91 61 21
2 12 42  92 62 22
3 13 43  93 63 23

[[3]]
  X8 X6
1 71 51
2 72 52
3 73 53

With ind defined as:

ind <- list(c(1, 4, 9),
            c(2, 5, 10, 7, 3),
            c(8, 6))

An option for a list of dfs:

map(ind, ~ map(df_list, `[`, .))

Upvotes: 1

ThomasIsCoding
ThomasIsCoding

Reputation: 102770

You can try the following base R solution using subset + Map

r <- Map(function(k) subset(df,select = k),ind)

such that

> r
[[1]]
   X1 X4 X9
1   1 31 81
2   2 32 82
3   3 33 83
4   4 34 84
5   5 35 85
6   6 36 86
7   7 37 87
8   8 38 88
9   9 39 89
10 10 40 90

[[2]]
   X2 X5 X10 X7 X3
1  11 41  91 61 21
2  12 42  92 62 22
3  13 43  93 63 23
4  14 44  94 64 24
5  15 45  95 65 25
6  16 46  96 66 26
7  17 47  97 67 27
8  18 48  98 68 28
9  19 49  99 69 29
10 20 50 100 70 30

[[3]]
   X8 X6
1  71 51
2  72 52
3  73 53
4  74 54
5  75 55
6  76 56
7  77 57
8  78 58
9  79 59
10 80 60

Upvotes: 0

Sotos
Sotos

Reputation: 51602

You can just do,

lapply(your_list, function(i) your_df[i])

Upvotes: 0

Related Questions