将 df 列表中的 df 随机分成相等的子集
Randomly divide df in list of df into equal subsets
昨天我已经问过类似的问题了:
我得到的答案几乎是我需要的,但仍然存在问题。我还考虑了其他不同的方法来获得结果。
这是我的示例 df-list:
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")
我想将列表中的单个 df 随机子集化为 n 个相等的部分(或尽可能接近相等)。我已经从 chinsoon12 那里得到了一个非常有用的答案:
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))})
问题是它对任意数量的行都不起作用,而且也没有考虑到所有观察结果。例如。当我使用该方法将我的 df_list 分成 5 个子集时,我得到 AB_df 的 325、324、324、324、324 的子集,总计不是 1624,所以缺少一些东西。当我将它分成 4 块时,我只得到 3 个子集...知道为什么会这样吗?
我还考虑了 2 种不同的方法来拆分列表中的 df。一种方法可能是通过随机更改行的顺序来随机重新排序观察结果:
for (a in 1:length(df_list)) {
df_list[[a]] = df_list[[a]][sample(nrow(df_list[[a]])),]}
现在我只需要将 dfs 分成 n 块...但这是我不确定如何做到这一点的地方。
我想到的第三种方法是为 n 个子样本创建一个随机数字列表 1:n,并将它们添加到数据帧中,然后根据数字提取 df。
我仍然认为第一种方法最简单,我更喜欢这种方法。知道代码有什么问题吗?
导致您的组大小不同的问题是一件很棘手的事情。它总是需要在一侧有一个硬间隔边界,我真的不知道在你的情况下该怎么做。
您可以使用 gl
解决您的问题,只需忽略警告即可。
当您在应用生成的级别之前随机化它们时,您就在那里。
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")
#the number of groups you want to generate
subs <- 4
splittedList <- lapply(df_list,
function(df){
idx <- gl(n = subs,round(nrow(df)/subs))
split(df, sample(idx))# randomize the groups
})
#> Warning in split.default(x = seq_len(nrow(x)), f = f, drop = drop, ...):
#> data length is not a multiple of split variable
#> Warning in split.default(x = seq_len(nrow(x)), f = f, drop = drop, ...):
#> data length is not a multiple of split variable
## the groups are appr. equally sized:
lapply(splittedList,function(l){sapply(l,nrow)})
#> $AB_df
#> 1 2 3 4
#> 406 406 406 406
#>
#> $BC_df
#> 1 2 3 4
#> 414 414 414 414
#>
#> $DE_df
#> 1 2 3 4
#> 414 414 414 414
#>
#> $FG_df
#> 1 2 3 4
#> 432 432 433 432
#>
#> $AB_pc
#> 1 2 3 4
#> 406 406 406 406
#>
#> $BC_pc
#> 1 2 3 4
#> 414 414 414 414
#>
#> $DE_pc
#> 1 2 3 4
#> 414 414 414 414
#>
#> $FG_pc
#> 1 2 3 4
#> 432 432 433 432
## and the sizes are right:
sapply(df_list,nrow)
#> AB_df BC_df DE_df FG_df AB_pc BC_pc DE_pc FG_pc
#> 1624 1656 1656 1729 1624 1656 1656 1729
sapply(splittedList,function(l){sum(sapply(l,nrow))})
#> AB_df BC_df DE_df FG_df AB_pc BC_pc DE_pc FG_pc
#> 1624 1656 1656 1729 1624 1656 1656 1729
昨天我已经问过类似的问题了:
我得到的答案几乎是我需要的,但仍然存在问题。我还考虑了其他不同的方法来获得结果。
这是我的示例 df-list:
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")
我想将列表中的单个 df 随机子集化为 n 个相等的部分(或尽可能接近相等)。我已经从 chinsoon12 那里得到了一个非常有用的答案:
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))})
问题是它对任意数量的行都不起作用,而且也没有考虑到所有观察结果。例如。当我使用该方法将我的 df_list 分成 5 个子集时,我得到 AB_df 的 325、324、324、324、324 的子集,总计不是 1624,所以缺少一些东西。当我将它分成 4 块时,我只得到 3 个子集...知道为什么会这样吗?
我还考虑了 2 种不同的方法来拆分列表中的 df。一种方法可能是通过随机更改行的顺序来随机重新排序观察结果:
for (a in 1:length(df_list)) {
df_list[[a]] = df_list[[a]][sample(nrow(df_list[[a]])),]}
现在我只需要将 dfs 分成 n 块...但这是我不确定如何做到这一点的地方。
我想到的第三种方法是为 n 个子样本创建一个随机数字列表 1:n,并将它们添加到数据帧中,然后根据数字提取 df。
我仍然认为第一种方法最简单,我更喜欢这种方法。知道代码有什么问题吗?
导致您的组大小不同的问题是一件很棘手的事情。它总是需要在一侧有一个硬间隔边界,我真的不知道在你的情况下该怎么做。
您可以使用 gl
解决您的问题,只需忽略警告即可。
当您在应用生成的级别之前随机化它们时,您就在那里。
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")
#the number of groups you want to generate
subs <- 4
splittedList <- lapply(df_list,
function(df){
idx <- gl(n = subs,round(nrow(df)/subs))
split(df, sample(idx))# randomize the groups
})
#> Warning in split.default(x = seq_len(nrow(x)), f = f, drop = drop, ...):
#> data length is not a multiple of split variable
#> Warning in split.default(x = seq_len(nrow(x)), f = f, drop = drop, ...):
#> data length is not a multiple of split variable
## the groups are appr. equally sized:
lapply(splittedList,function(l){sapply(l,nrow)})
#> $AB_df
#> 1 2 3 4
#> 406 406 406 406
#>
#> $BC_df
#> 1 2 3 4
#> 414 414 414 414
#>
#> $DE_df
#> 1 2 3 4
#> 414 414 414 414
#>
#> $FG_df
#> 1 2 3 4
#> 432 432 433 432
#>
#> $AB_pc
#> 1 2 3 4
#> 406 406 406 406
#>
#> $BC_pc
#> 1 2 3 4
#> 414 414 414 414
#>
#> $DE_pc
#> 1 2 3 4
#> 414 414 414 414
#>
#> $FG_pc
#> 1 2 3 4
#> 432 432 433 432
## and the sizes are right:
sapply(df_list,nrow)
#> AB_df BC_df DE_df FG_df AB_pc BC_pc DE_pc FG_pc
#> 1624 1656 1656 1729 1624 1656 1656 1729
sapply(splittedList,function(l){sum(sapply(l,nrow))})
#> AB_df BC_df DE_df FG_df AB_pc BC_pc DE_pc FG_pc
#> 1624 1656 1656 1729 1624 1656 1656 1729