R拆分DF并且并行运行测试

时间:2017-12-12 00:49:42

标签: r parallel-processing

我有两个矩阵,我想做几个统计,我将dataframe1的每一行与dataframe2进行比较。这些是大型数据框架(300,000行和40,000行),因此需要进行比较。

我做了一些函数来应用统计数据。我想知道的是,是否可以将dataframe1拆分成块,并在多个核心上并行运行这些块。

library(lawstat)
library(reshape2)
df1 = matrix(ncol= 100, nrow=100)
for ( i in 1:100){
  df1[,i] =floor(runif(100, min = 0, max =3))
}

df2 = matrix(ncol= 100, nrow=1000)
for ( i in 1:100){
  df2[,i] =runif(1000, min = 0, max =1000)
}

testFunc<- function(df1, df2){
      x=apply(df1, 1, function(x) apply(df2, 1, function(y) levene.test(y,x)$p.value))
      x=melt(x)
      return(x)
    }

system.time(res <- testFunc(df1,df2 ))

一些统计数据(例如levene测试)需要相当长的时间来计算,所以任何我可以加快速度的方法都会很棒。

1 个答案:

答案 0 :(得分:2)

您的功能有优化空间,但以下是使用parallel包进行改进的示例:

library(parallel)
library(snow)

# I have a quad core processor so I am using 3 cores here.
cl <- snow::makeCluster(3)
testFunc2<- function(df1, df2){
  x=parallel::parApply(cl = cl, X = df1, 1, function(x, df2) apply(df2, 1, 
function(y) lawstat::levene.test(y,x)$p.value), df2)
  x=melt(x)
  return(x)
}
system.time(res <- testFunc2(df1,df2 ))

在我的机器上,如果群集大小为3,则至少将运行时间减半。

编辑:我觉得你的代码不好,所以下面是一个精简的levene.test函数,可以提高大多数家庭/工作机器上的性能。

lev_lite = function(y, group){
  N = 100 # or length(y)
  k = 3   # or length(levels(group)) after setting to as.factor below

  reorder <- order(group)
  group <- group[reorder]
  y <- y[reorder]
  group <- as.factor(group)
  n <- tapply(y,group, FUN = length)
  yi_bar <- tapply(y,group, FUN = median)
  zij = abs(y - rep(yi_bar, n))
  zidot = tapply(zij, group, FUN = mean)
  zdotdot = mean(zij)
  # test stat, see wiki
  W = ((N - k)/(k - 1)) * (
    sum(n*(zidot - zdotdot)^2)/
      sum((zij - rep(zidot, n))^2))

  #p val returned
  1 - pf(W, k-1, N-k)
}

testFunc2<- function(df1, df2){
  x=apply(df1, 1, function(x) apply(df2, 1, lev_lite, group = x))
  x=melt(x)
  return(x)
}

> system.time(res <- testFunc(df1[1:50, ],df2[1:50,] ))
user  system elapsed 
5.53    0.00    5.56 
> system.time(res2 <- testFunc2(df1[1:50, ],df2[1:50, ] ))
user  system elapsed 
1.13    0.00    1.14 
> max(res2 - res)
[1] 2.220446e-15

这是没有并行化的约5倍。