我有一个大型数据集(超过2000万个障碍物),我使用survey
包进行分析,运行简单查询需要花费很多时间。我试图找到一种方法来加快我的代码,但我想知道是否有更好的方法来提高效率。
在我的基准测试中,我使用svyby
/ svytotal
来比较三个命令的速度:
svyby
/ svytotal
foreach
dopar
进行并行计算Spoiler:选项3的速度是第一个选项的两倍以上它不适合大型数据集,因为它依赖于并行计算,并且在处理大数据时会快速达到内存限制集。尽管我有16GB的RAM,但我也遇到了这个问题。有一些solutions to this memory limitation,但它们都不适用于调查设计对象。
有关如何加快速度而不是因内存限制而崩溃的任何想法?
# Load Packages
library(survey)
library(data.table)
library(compiler)
library(foreach)
library(doParallel)
options(digits=3)
# Load Data
data(api)
# Convert data to data.table format (mostly to increase speed of the process)
apiclus1 <- as.data.table(apiclus1)
# Multiplicate data observations by 1000
apiclus1 <- apiclus1[rep(seq_len(nrow(apiclus1)), 1000), ]
# create a count variable
apiclus1[, Vcount := 1]
# create survey design
dclus1 <- svydesign(id=~dnum, weights=~pw, data=apiclus1, fpc=~fpc)
t1 <- Sys.time()
table1 <- svyby(~Vcount,
~stype+dnum+cname,
design = dclus1,
svytotal)
T1 <- Sys.time() - t1
# in this option, I create a list with different subsets of the survey design
# that will be passed to different CPU cores to work at the same time
subdesign <- function(i){ subset(dclus1, dnum==i)}
groups <- unique(apiclus1$dnum)
list_subsets <- lapply(groups[], subdesign) # apply function and get all subsets in a list
i <- NULL
# Start Parallel
registerDoParallel(cores=7)
t2 <- Sys.time()
table2 <- foreach (i = list_subsets, .combine= rbind, .packages="survey") %dopar% {
options( survey.lonely.psu = "remove" )
svyby(~Vcount,
~stype+dnum+cname,
design = i,
svytotal)}
T2 <- Sys.time() - t2
# make a function of the previous query
query2 <- function (list_subsets) { foreach (i = list_subsets, .combine= rbind, .packages="survey") %dopar% {
svyby(~Vcount,
~stype+dnum+cname,
design = i,
svytotal)}}
# Compile the function to increase speed
query3 <- cmpfun(query2 )
t3 <- Sys.time()
table3 <- query3 (list_subsets)
T3 <- Sys.time() - t3
>T1: 1.9 secs
>T2: 1.13 secs
>T3 0.58 secs
barplot(c(T1, T2, T3),
names.arg = c("1) simple table", "2) parallel", "3) compiled parallel"),
ylab="Seconds")
答案 0 :(得分:6)
感谢您提出这个问题。在R中使用大型调查数据集高效工作可能需要一些基本的SQL语法(比R更容易学习)。 MonetDB是唯一与survey
软件包兼容的大数据选项,探索其他高性能软件包(可能)并不会有成效。通常当我正在探索一个巨大的数据集时,我直接在SQL查询中编写而不是使用调查包,因为标准错误计算是计算密集型的(并且在交互式数据探索期间差异不那么有用)。注意最后的SQL时间戳如何吹走所有其他选项。要计算快速加权平均值,请使用类似"SELECT by_column , SUM( your_column * the_weight ) / SUM( the_weight ) FROM yourdata GROUP BY by_column"
当您确实需要交互式标准错误时,线性化(svydesign
)通常比复制(svrepdesign
)更加计算密集,但有时会创建复制设计(就像我使用{{{ 1}}以下)需要比一些用户更熟悉的更多调查方法。
jk1w_dclus1