在R中生成具有随机选择特征的数据集列表



我有一个包含20个特性的数据集。我希望从原始数据集中创建一个具有随机特征子集的数据集列表。例如-[dataset[, c(1,3,4)], dataset[, c(2,3,5,11,20)]]

我正在为同一尝试以下代码

selectors = array(runif(2000), dim=c(100, 20, 1))
list_datasets = vector("list", 100)
i = 1
while(i < 100)
list_datasets[[i]] = dataset[, selectors[i,,1] > 0.5]
i = i + 1

这里,我的dataset有20个特征,我需要这20个特征中的100个具有随机特征的数据集。因此,我创建了selectors数组,最初创建了一个大小为2000的带有随机值的向量,然后使其为100*20。在while循环中,只有当为其生成的随机值大于0.5时,我才尝试向list_datasets[[i]]添加一个特性。希望我能够解释自己的

但这是非常缓慢的。我是R的新手,想知道什么是实现我想要做的事情的最佳方式。

我不完全确定我是否理解您的设置,所以如果我遗漏了什么,请纠正我。我的理解是,您有一个数据集(我创建了一个大小为100行x 20个特征的假数据集),并希望使用特征的随机子集创建100个新数据集。通过生成随机统一值并检查每个值是否大于0.5,可以生成特征的随机子集。

这里有两个选项,一个使用lapply,另一个使用for循环。

apply函数通常比循环快(我认为您希望使用for循环,而不是while循环)。

其他变化:

1) 使用@Krash建议的布尔掩码,因为您可以在循环外检查每个值是否大于0.5,因为它是否大于0.5并不取决于i

2)selectors可以是2d

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

最新更新