我不确定我是否理解您的设置,如果我遗漏了什么,请纠正我。我的理解是你有一个数据集(我创建了一个大小为 100 行 x 20 个特征的假数据集),并且想要使用随机的特征子集创建 100 个新数据集。您通过生成随机统一值并检查每个值是否 > 0.5 来生成随机特征子集。
我在这里有两种选择,一种使用lapply,另一种使用for 循环。
apply 函数通常比循环快(而且我认为你想在这里使用for 循环,而不是while 循环)。
其他变化:
1) 使用@Krash 建议的布尔掩码,因为您可以在循环外检查每个值是否大于 0.5,因为它是否不取决于i。
2) selectors 可以是二维的
set.seed(123)
# Original dataset: assume it's 100 x 20 features
dataset <- array(rnorm(2000), dim = c(100, 20))
## Original (Option 0: while loop)
system.time({
# Select features: 100 x 20 x 1 (one row per dataset)
selectors = array(runif(2000), dim = c(100, 20, 1));
# Initialize list
list_datasets = vector("list", 100);
# Fill in list
i = 1;
while(i < 100) {
list_datasets[[i]] = dataset[, selectors[i,,1] > 0.5];
i = i + 1 # This causes an off-by-one error, as list_datasets[[100]] is never filled in
}
})
## user system elapsed
## 0.006 0.000 0.006
# Option 1: for loop
system.time({
# Select: boolean mask: 100 x 20 (need one row to create each dataset)
selectors = array(runif(2000), dim = c(100, 20));
selectors = selectors < 0.5
# Initialize list
list_datasets = vector("list", 100);
# Fill in list
for (i in 1:100) {
list_datasets[[i]] = dataset[ , selectors[i, ]]
}
})
## user system elapsed
## 0.004 0.000 0.005
# Option 2: lapply
system.time({
# Select: boolean mask: 100 x 20 (need one row to create each dataset)
selectors = array(runif(2000), dim = c(100, 20));
selectors = selectors < 0.5
# Fill in list
list_datasets <- lapply(1:100, FUN = function(x) dataset[ , selectors[x, ]])
})
## user system elapsed
## 0.003 0.000 0.003
显然,每次运行语句所花费的时间都会有所不同,但希望其中一些建议的更改会提高速度。
就像检查代码是否符合我的要求:
# Check number of cols per dataset
list_datasets %>%
purrr::map_int(~ncol(.))
## [1] 8 7 9 12 11 13 11 10 10 14 14 7 8 10 10 9 14 10 6 11 13 8 7 8 10 12 9 11 9 9 13
## [32] 12 8 14 11 11 8 10 11 8 10 13 12 10 6 10 10 12 9 9 10 11 7 8 11 9 11 9 7 9 9 11
## [63] 14 9 9 9 9 13 13 14 12 9 10 9 12 8 11 14 9 7 12 7 6 11 11 7 9 8 12 10 12 9 11
## [94] 13 12 16 9 8 11 10
其他想法:您可以在循环中添加这样的一行(或lapplyFUN),而不是通过随机制服创建selectors 数组,每行对应一个新数据集。
include_feature <- sample(0:1, size = 20, replace = TRUE)
include_feature
## [1] 0 0 1 0 0 0 1 1 1 0 1 1 1 0 1 0 0 0 0 1