r语言 - 如何抽样(替换和权重)超过.machine $整数.最大行从一个数据表?



我想从数据中取一个样本。大于R整数极限的表(可通过.Machine$integer.max获得)。以下是我尝试过的:

library(bit64)
library(data.table)
irisdt <- as.data.table(iris)
test <- slice_sample(irisdt, n = .Machine$integer.max + 100, weight_by = Sepal.Length, replace = T)
Fehler in sample.int(n, size, prob = wt, replace = TRUE) : 
ungültiges 'size' Argument (= invalid argument 'size')
Zusätzlich: Warnmeldung:
In sample.int(n, size, prob = wt, replace = TRUE) :
NAs introduced by coercion to integer range

如果我将n参数转换为slice_sample到integer64,我得到一个空样本。

> test <- slice_sample(irisdt, n = as.integer64(.Machine$integer.max + 100),
weight_by = Sepal.Length, replace = T)
> nrow(test)
[1] 0

我不能取几个更小的样本,这显然是解决问题的办法。

你还有别的主意吗?谢谢你!

我认为这里有两个问题:

  • 首先是@Waldi对数据的评论。
  • 第二个sample函数,其中大小参数不能超过.Machine$integer.max,参见文档:

n或x的非整数正数值将被截断为下一个最小的整数,该整数不得大于。machine $integer.max.

您可以尝试小于或等于.Machine$integer.max的任何大小

irisdt[sample(.N , .Machine$integer.max - 2e9 , replace = T) ,]

适合我(减去2e9内存限制)

由于data.table不允许超过.Machine$integer.max行,您可以将arrowdplyrfurrr一起使用:

library(bit64)
library(data.table)
library(arrow)
library(dplyr)
library(furrr)
irisdt <- as.data.table(iris)
# Split job
target = .Machine$integer.max+1000
split = 100
# Distribute calculations
numcalc <- rep(round(target/split),split)
numcalc[split] <- numcalc[split] + target - sum(numcalc)
plan(multisession, workers = nbrOfWorkers()-1)
# Generate files in parallel
numcalc %>% furrr::future_iwalk(~{
test <- irisdt %>% slice_sample( n = .x , weight_by = Sepal.Length, replace = T) 
write_dataset(test,paste0('D:/test/test',.y,'.parquet'),format = 'parquet')
},.options = furrr_options(seed = TRUE))
# Open dataset
ds <- open_dataset('D:/test',format='parquet')
ds
#FileSystemDataset with 100 Parquet files
#Sepal.Length: double
#Sepal.Width: double
#Petal.Length: double
#Petal.Width: double
#Species: dictionary<values=string, indices=int32>
result <- ds %>% group_by(Species) %>% summarize(n=n()) %>% collect() 
result
# A tibble: 3 x 2
#  Species            n
#  <fct>          <int>
#1 virginica  807049123
#2 versicolor 727198323
#3 setosa     613237201

sum(result$n)-.Machine$integer.max
#[1] 1000

最新更新