【问题标题】:Randomly split a dataframe in n equal pieces将数据帧随机分成 n 等份
【发布时间】:2020-02-05 20:31:17
【问题描述】:

假设我有一个不同行数的数据框列表:

AB_df = data.frame(replicate(2,sample(0:130,201,rep=TRUE)))
BC_df = data.frame(replicate(2,sample(0:130,200,rep=TRUE)))
DE_df = data.frame(replicate(2,sample(0:130,197,rep=TRUE)))
FG_df = data.frame(replicate(2,sample(0:130,203,rep=TRUE)))

AB_pc = data.frame(replicate(2,sample(0:130,201,rep=TRUE)))
BC_pc = data.frame(replicate(2,sample(0:130,200,rep=TRUE)))
DE_pc = data.frame(replicate(2,sample(0:130,197,rep=TRUE)))
FG_pc = data.frame(replicate(2,sample(0:130,203,rep=TRUE)))

df_list = list(AB_df, BC_df, DE_df, FG_df, AB_pc, BC_pc, DE_pc, FG_pc)
names(df_list) = c("AB_df", "BC_df", "DE_df", "FG_df", "AB_pc", "BC_pc", "DE_pc", "FG_pc")

我想将嵌套的数据帧分成 n 个相等但随机的部分,以便我有例如对于 4 个 4 个 50 行的数据帧和 1 个 51 行的数据帧。在任何拆分的数据帧中,任何行都不应重复。

结构应该是:

List of 8
 $ AB_df: list of 4
      $ AB_df1: "data.frame": 50 obs. of 2 variables
          ..$ X1: int [1:50] 88 128....
          ..$ X2: int [1:50] 12 84 ....
      $ AB_df2: "data.frame": 50 obs. of 2 variables
          ..$ X1: int [1:50] numbers...
          ..$ X2: int [1:50] numbers....
      $ AB_df3: "data.frame": 50 obs. of 2 variables
          ..$ X1: int [1:50] numbers...
          ..$ X2: int [1:50] numbers....
      $ AB_df4: "data.frame": 51 obs. of 2 variables
          ..$ X1: int [1:50] numbers...
          ..$ X2: int [1:50] numbers....
 $ BC_df:'list of 4
      $ BC_df1: "data.frame": 50 obs. of 2 variables
          ..$ X1: int [1:50] numbers...
          ..$ X2: int [1:50] numbers....
      $ BC_df2: "data.frame": 50 obs. of 2 variables
          ..$ X1: int [1:50] numbers...
          ..$ X2: int [1:50] numbers....
 ............................

我发现了几个关于如何随机拆分数据框的主题,但这些主题都没有帮助我解决我的问题。

更新:由于某种原因,这只给了我 3 个拆分的数据帧。

set.seed(0L)
AB_df = data.frame(replicate(2,sample(0:130,1624,rep=TRUE)))
BC_df = data.frame(replicate(2,sample(0:130,1656,rep=TRUE)))
DE_df = data.frame(replicate(2,sample(0:130,1656,rep=TRUE)))
FG_df = data.frame(replicate(2,sample(0:130,1729,rep=TRUE)))

AB_pc = data.frame(replicate(2,sample(0:130,1624,rep=TRUE)))
BC_pc = data.frame(replicate(2,sample(0:130,1656,rep=TRUE)))
DE_pc = data.frame(replicate(2,sample(0:130,1656,rep=TRUE)))
FG_pc = data.frame(replicate(2,sample(0:130,1729,rep=TRUE)))

df_list = list(AB_df, BC_df, DE_df, FG_df, AB_pc, BC_pc, DE_pc, FG_pc)
names(df_list) = c("AB_df", "BC_df", "DE_df", "FG_df", "AB_pc", "BC_pc", "DE_pc", "FG_pc")

new = lapply(df_list, function(df) {
  n <- nrow(df)
  split(df, cut(sample(n), seq(1, n, by=floor(n/4)), labels=FALSE, include.lowest=TRUE))})

【问题讨论】:

  • 不是关于实际问题,但仅供参考 purrr::lst 完成您在 listnames(df_list) 行中所做的工作

标签: r list dataframe random sample


【解决方案1】:

您可以使用cutsplit 来执行此操作:

k <- 4
str(
    lapply(df_list, function(df) {
        n <- nrow(df)
        split(df, cut(sample(n), seq(0, (k+1)*ceiling(n/k), by=ceiling(n/k)), labels=FALSE))
    })
)

输出:

List of 8
 $ AB_df:List of 4
  ..$ 1:'data.frame':   51 obs. of  2 variables:
  .. ..$ X1: int [1:51] 13 50 84 6 109 125 88 120 38 41 ...
  .. ..$ X2: int [1:51] 36 107 14 71 92 115 130 126 111 67 ...
  ..$ 2:'data.frame':   50 obs. of  2 variables:
  .. ..$ X1: int [1:50] 42 105 73 72 36 69 110 43 118 121 ...
  .. ..$ X2: int [1:50] 23 81 96 52 97 42 82 102 89 89 ...
  ..$ 3:'data.frame':   50 obs. of  2 variables:
  .. ..$ X1: int [1:50] 67 128 78 105 32 41 19 86 69 120 ...
  .. ..$ X2: int [1:50] 116 85 55 1 110 96 67 101 73 48 ...
  ..$ 4:'data.frame':   50 obs. of  2 variables:
  .. ..$ X1: int [1:50] 20 104 33 83 73 24 23 129 44 69 ...
  .. ..$ X2: int [1:50] 13 100 74 14 0 59 55 80 72 2 ...
 $ BC_df:List of 4
  ..$ 1:'data.frame':   51 obs. of  2 variables:
  .. ..$ X1: int [1:51] 58 85 40 68 30 32 111 96 35 51 ...
  .. ..$ X2: int [1:51] 71 24 12 50 87 61 17 65 11 43 ...
  ..$ 2:'data.frame':   50 obs. of  2 variables:
  .. ..$ X1: int [1:50] 10 54 91 105 65 39 26 78 123 12 ...
  .. ..$ X2: int [1:50] 117 31 6 114 73 11 58 93 106 21 ...
.........................................................

数据:

set.seed(0L)    
AB_df = data.frame(replicate(2,sample(0:130,201,rep=TRUE)))
BC_df = data.frame(replicate(2,sample(0:130,200,rep=TRUE)))
DE_df = data.frame(replicate(2,sample(0:130,197,rep=TRUE)))
FG_df = data.frame(replicate(2,sample(0:130,203,rep=TRUE)))

AB_pc = data.frame(replicate(2,sample(0:130,201,rep=TRUE)))
BC_pc = data.frame(replicate(2,sample(0:130,200,rep=TRUE)))
DE_pc = data.frame(replicate(2,sample(0:130,197,rep=TRUE)))
FG_pc = data.frame(replicate(2,sample(0:130,203,rep=TRUE)))

df_list = list(AB_df, BC_df, DE_df, FG_df, AB_pc, BC_pc, DE_pc, FG_pc)
names(df_list) = c("AB_df", "BC_df", "DE_df", "FG_df", "AB_pc", "BC_pc", "DE_pc", "FG_pc")

【讨论】:

  • 谢谢!我要试试这个。
  • 如何定义 n。应该是行数吧?
  • 抱歉。已经修好了
  • 还有一个问题。这似乎完全符合我的要求。但是在我真正的 df 中,我经常只得到一些数据帧的 3 个子集,即使我划分了 4 个......知道为什么吗?我在答案中更新了我的数据框,请看一下。当我使用不同的行数时,AB_df 中只有 3 个数据框...
  • 抱歉打错字了。我的意思是n &lt;- 1624; k &lt;- 5; lengths(split(1:n, cut(1:n, seq(0, n*(1+1/k), by=ceiling(n/k)))))。已在上面的代码中修复它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-06
  • 1970-01-01
  • 2020-12-12
  • 2017-03-10
相关资源
最近更新 更多