R-加速循环

时间:2018-07-14 17:21:54

标签: r performance loops

我想知道是否可以加快循环速度,我想知道您是否可以帮助我解决这个问题。

我已经使用了所有技巧,但我仍然认为这还不够。

问题在于从一年df减去下一年df的金额。我有2个数据框:

df_2016 <- data.frame(
  subject = rep(1:195, 65*39),
  items = rep(1:39, 195*65),
  sub_items = rep(1:65, 195*39),
  value = sample(1:100000000,(195*65*39)),
  period = rep("2016",(195*65*39)))

   df_2016 <- df_2016[sample(1:(195*65*39),450000),] # See Reference "A" below

df_2017 <- data.frame(
  subject = rep(1:195, 65*39),
  items = rep(1:39, 195*65),
  sub_items = rep(1:65, 195*39),
  value = sample(1:100000000,(195*65*39)),
  period = rep("2017",(195*65*39)))

简而言之,有3个类别变量和1个数字。一个数据集具有2016年的数量,另一个数据集具有2017年的数量。

我想从2017年的金额中减去2016年的金额,相同的“主题”和相同的“项目”以及相同的“ sub_items”。 (参考文献A)没有重复的行,但是可能发生的是2017年的一行没有2016年的一对;如果有一对,则只有一个。

我使用“级联子集”实现了此功能,但它确实确实加快了我的功能,但还不够:

Func_diff <- function (df_per = df_2017, df_it = df_2016){

  func_df <<- df_per[1,1:5]   # i create the df where i'm going to put the outputs

  y <- 1

  subject_v <- sort(unique(df_per$subject))


  # 0 # Loop over subject

  for (j in 1:length(subject_v)) {

    df_per_w <- df_per[df_per$subject == subject_v[j], ]
    df_it_w <- df_it[df_it$subject == subject_v[j], ]

    item_v <- sort(unique(df_per_w$items))


  # 2 #  . Loop1 over items

  for (w in 1:length(item_v)){

      sub_item_v <- sort(unique(df_per_w[df_per_w$items == item_v[w], 3]))


  # 3 # Loop over subitems

  for(z in 1:length(sub_item_v)){

      dfcara_per <- df_per_w[df_per_w$items == item_v[w] & df_per_w$sub_items == sub_item_v[z],]
      dfcara_it <- df_it_w[df_it_w$items == item_v[w] & df_it_w$sub_items == sub_item_v[z],]


  # 4 # Loop over selected rows: subject[j], items[w], sub_items[z]

  for (i in 1:nrow(dfcara_per)) {

          # Checks if that combination of subject, item and subitem, existed the year before:

  if(length(dfcara_it[dfcara_it$subject == dfcara_per[i,1] &
                              dfcara_it$items == dfcara_per[i,2] &
                              dfcara_it$sub_items == dfcara_per[i,3], 4]) != 0) {

  func_df[y,1:5] <<- c(

              dfcara_per[i,1:3],

              sum(dfcara_per[i,4] -
                    dfcara_it[
                      dfcara_it$subject == dfcara_per[i,1] &
                      dfcara_it$items == dfcara_per[i,2] &
                      dfcara_it$sub_items == dfcara_per[i,3], 
                              4]),

              dfcara_per[i,5]
                       )

          }else{

            func_df[y,1:5] <<- func_df[i,1:5] # If there is no data in 2016, the function saves the amount of 2017

          }

          y <- y + 1  

        } 
      }
    }
  }

} # Function . End

它可以工作,但是要花很长时间,而且我不明白为什么简单的操作要花这么长时间。

先谢谢您!

1 个答案:

答案 0 :(得分:2)

您的问题在于数据的生成。 subjectitemssub_items的结构不会导致subjectitemssub_items的唯一组合,因此违反了您的假设

  

没有重复的行,

我尝试使用subject函数创建具有itemssub_itemsexpand.grid()唯一组合的另一版本的数据。

DF2016 <- data.frame(expand.grid(1:195,1:65,1:39), 
                     value = sample(1:100000000,(195*65*39)),
                     period = rep("2016",(195*65*39)))

DF2016 <- DF2016[sample(1:(195*65*39),450000),]

DF2017 <- data.frame(expand.grid(1:195,1:65,1:39), 
                     value = sample(1:100000000,(195*65*39)),
                     period = rep("2017",(195*65*39)))

变量Var1Var2Var3对应于subjectitemssub_items

然后您可以生成左联接以合并两个数据集

library("dplyr")
res <- DF2017 %>% left_join(DF2016, by=c("Var1", "Var2", "Var3")) %>% 
       mutate(difference = value.x-value.y)

2017年的值表示为value.x,2016年的值表示为value.y。这样产生

> head(res)
  Var1 Var2 Var3  value.x period.x  value.y period.y difference
1    1    1    1 94920289     2017 84618631     2016   10301658
2    2    1    1 31008444     2017 87524572     2016  -56516128
3    3    1    1 44687050     2017       NA     <NA>         NA
4    4    1    1 87458715     2017 83105988     2016    4352727
5    5    1    1 40977802     2017 22528409     2016   18449393
6    6    1    1 80460053     2017       NA     <NA>         NA