根据行号矩阵对数据框进行子集处理,然后将结果保存在一个列表中

时间:2018-06-30 14:53:36

标签: r list loops dataframe subset

我有一个名为 df 的数据框,如下所示:

> df
   Date  A  B  C
1  2001  1 12 14
2  2002  2 13 15
3  2003  3 14 16
4  2004  4 15 17
5  2005  5 16 18
6  2006  6 17 19
7  2007  7 18 20
8  2008  8 19 21
9  2009  9 20 22
10 2010 10 21 23

和名为 index 的矩阵,如下所示:

> index
     Resample01 Resample02 Resample03 Resample04 Resample05
[1,]          1          7          1          2          7
[2,]          3          9          2          3          8
[3,]          5          1          3          8          1
[4,]          8          3          4          9          4
[5,]         10          4          5         10          9

每列中的数字代表要选择的行号。

  

目标是根据矩阵“索引”的每一列中的行号将数据帧分为“火车”和“测试”两个排他的组。例如,对于“ Resample01”,结果应类似于:

> train
   Date  A  B  C
1  2001  1 12 14
3  2003  3 14 16
5  2005  5 16 18
8  2008  8 19 21
10 2010 10 21 23

> test
  Date A  B  C
2 2002 2 13 15
4 2004 4 15 17
6 2006 6 17 19
7 2007 7 18 20
9 2009 9 20 22

并且应该对“索引”中的每个列执行此过程,并且结果应保存在“培训”和“测试”的两个列表中,其中“培训”类似于:

$train1
       Date  A  B  C
    1  2001  1 12 14
    3  2003  3 14 16
    5  2005  5 16 18
    8  2008  8 19 21
    10 2010 10 21 23

$train2
:
:
$train5

和“测试”应采用相同的格式。

仅需注意,我的 df 累计包含43,000个观察值,而 index 矩阵具有2000列和20,000多个行。我知道,通过执行以下操作,为一列子集设置很容易:

test = df[-c(index[,1]),]

但是对于多列,我不知道如何执行(或循环执行),并且列表的保存形式似乎也很困难。

2 个答案:

答案 0 :(得分:4)

您可以尝试这样的操作。结果的长度应为ncol(index),每个元素应包含两个列表元素,每个元素用于训练和测试数据集。

apply(index, MARGIN = 2, FUN = function(x, data) {
  # is is "demoted" from a column to a vector
  list(train = data[x, ], test = data[-x, ])
}, data = df)

答案 1 :(得分:0)

akrun的解决方案解决了我的问题。

通过@RomanLuštrik代码:

listofsample = apply(index, MARGIN = 2, FUN = function(x, data) {
  list(train = df[x, ], test = df[-x, ])
 }, data = df)

以下来自akrun的代码:

train = sapply(listofsample, `[`,1)
test = sapply(listofsample, `[`,2)

它会产生我想要的两个列表。