R将嵌套for循环转换为lapply()以获得更好的性能

时间:2018-02-01 22:35:12

标签: r performance for-loop nested-loops

由于速度原因,我很难将嵌套的for循环转换为lapply()。

我有2个data.tables,我循环每一行,以便比较它的内容,如果相等,做一些计算。它花了我超过10分钟。为我的大约1000行和360行的数据集进行计算。

在下面这个最小的例子中,它不到一秒,但每个只有3个。

库(data.table) 库(tictoc)

name <- c(rep("apple",2), rep("banana",2), rep("citrus", 2))
stim <- c("nc","alk" ,"nc",  "lem", "haz", "nc")
vis <- c(1, 1, 1, 1, 6, 7)
f <-c(2,2,2,1,3,3)
g <-c(2,2,2,2,4,4)
h <- c(rep(2,6))
value<- c(5,10,5,10,10,5)

tab <- data.table(name, stim, vis, f,g,h,value)

tab1 <- tab[stim == "nc"]
tab2 <- tab[!(stim == "nc")]


tic("looping")

for(i in 1:NROW(tab1)){
  for (n in 1: NROW((tab2))){
    if(identical(tab2[n,name],tab1[i,name])

    & identical(tab2[n,vis],tab1[i,vis])
      & identical(tab2[n,3:(length(tab2)-1), with = FALSE],tab1[i,3:(length(tab1)-1), with = FALSE])){

      tab2[n,"value"] <- tab2[n, "value"] - tab1[i,"value"]
    }  
  }

}
toc()

我一直在寻找申请家庭,这似乎是一种方法,但我无法弄清楚如何解决它。我感谢任何帮助!

编辑: 循环之前: tab1看起来像这样:

     name stim vis f g h value
1:  apple   nc   1 2 2 2     5
2: banana   nc   1 2 2 2     5
3: citrus   nc   7 3 4 2     5

tab2如下所示:

     name stim vis f g h value
1:  apple  alk   1 2 2 2    10
2: banana  lem   1 1 2 2    10
3: citrus  haz   6 3 4 2    10

循环后(仅对tab2感兴趣)预期结果:

     name stim vis f g h value
1:  apple  alk   1 2 2 2     5
2: banana  lem   1 1 2 2    10
3: citrus  haz   6 3 4 2    10

1 个答案:

答案 0 :(得分:2)

应用循环不会加速您的计算。实际上它 WILL 会让它变慢,因为你已经定义了data.frames,而你只是在替换值。

相反,我建议使用合并的替代方法。 (注意:您的代码有一些错误并且没有运行,所以我希望我正确地解释您的意图。如果没有,请告诉我。)

> merge(tab1, tab2, by = c("name", "vis", "f", "g", "h"), suffixes=c("1", "2"), all.y=T) -> tab3
> tab3$value <- tab3$value2-tab3$value1
> tab3
    name vis f g h stim1 value1 stim2 value2 value
1  apple   1 2 2 2    nc      5   alk     10     5
2 banana   1 1 2 2  <NA>     NA   lem     10    NA
3 citrus   6 3 4 2  <NA>     NA   haz     10    NA

您可以根据需要重命名或移动列。