【问题标题】:subset a dataframe based on a matrix of row numbers and save the result in one list根据行号矩阵对数据帧进行子集化并将结果保存在一个列表中
【发布时间】:2018-12-09 11:44:56
【问题描述】:

我有一个名为 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

并且这个过程应该对“index”中的每一列进行,结果应该保存在“train”和“test”两个列表中,其中“train”是这样的:

$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

和“test”的格式应该一样。

请注意,我的 df 实际包含 43,000 个观察值,而 index 矩阵有 2000 列和 20,000 多行。我知道一列的子集很容易,通过这样做:

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

但是对于多列我不知道怎么做(或循环它),并且列表的保存形式似乎也很困难。

【问题讨论】:

    标签: r list loops dataframe subset


    【解决方案1】:

    你可以试试这样的。结果的长度应为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)
    

    【讨论】:

    • 不清楚为什么要使用“数据”参数。它不是应用中的命名形式,您在 FUN 参数中没有提及它。 (我仍然认为你的代码会成功,尽管我会使用sapply。)
    • 谢谢,代码有效。然而,结果是一个列表:sample 01 (train)(test),sample 02(train)(test),....sample2000 (train)(test)。我希望有两个列表:train01 (sample01),train02(sample02),...,train2000(sample2000)。 &test 01(sample01),test02(sample02),...,test2000(sample2000)。也许我可以通过运行 train = apply(train.index, MARGIN = 1, FUN = function(x, data) { list(train = sample_N_new_env[x, ])}, data = sample_N_new_env)[test = apply(train.index, MARGIN = 1, FUN = function(x, data) { list(test = sample_N_new_env[-x, ])}, data = sample_N_new_env)] 来做到这一点
    • @42- 这是一个错字,df --> 数据。我已经更正了。
    【解决方案2】:

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

    @Roman Luš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)
    

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

    【讨论】:

      猜你喜欢
      • 2016-12-25
      • 1970-01-01
      • 2015-01-17
      • 2019-04-24
      • 2018-11-05
      • 2013-04-13
      • 2019-10-21
      • 1970-01-01
      相关资源
      最近更新 更多