在这种情况下,为什么管道这么慢?

时间:2018-01-30 10:16:54

标签: r performance dplyr ode

我在R中运行的模型运行速度非常慢,我发现它纯粹是由于使用了ode求解器中的管道的极少数代码行。有谁知道为什么这会减慢这么多?有没有更快的方法呢?

示例代码:

IDS <- c(1,1,2)
output <- runif(3, 0, 100)
ID_df1 <- data.frame(IDS, output)
ID_df <- ID_df1 %>% 
  group_by(IDS) %>% 
  summarise(totals = sum(output))
portions <- ID_df1 %>% 
  left_join(ID_df, by = "IDS") %>% 
  mutate(portion = output/totals) %>% 
  select(IDS, portion)

2 个答案:

答案 0 :(得分:1)

建议使用data.table。下面的一些时间比较:

multiplier = FARE_CLASS_MULTIPLIER_DICTIONARY[airline_name][fare_class]

答案 1 :(得分:1)

基础R tapply运行得更快。

ID_df1$portion <- unlist(tapply(ID_df1$output, ID_df1$IDS, function(x) x / sum(x)))

进行比较(我使用的是10,000行和100个不同IDS的数据框)

set.seed(pi)
IDS <- sample(1:100, size = 10000, replace = TRUE)
output <- runif(3, 0, 10000)
ID_df1 <- data.frame(IDS, output)

library(data.table)
library(dplyr)
library(microbenchmark)
microbenchmark(
  orig = {
    ID_df <- ID_df1 %>% 
      group_by(IDS) %>% 
      summarise(totals = sum(output))
    portions <- ID_df1 %>% 
      left_join(ID_df, by = "IDS") %>% 
      mutate(portion = output/totals) %>% 
      select(IDS, portion)
  },
  tino = {
    ID_df1 %>% group_by(IDS) %>% mutate(portion = output / sum(output))
  },
  data.table = {
    setDT(ID_df1)[, .(portion = output / sum(output)), by=.(IDS)]
  },
  base = {
    ID_df1$portion <- unlist(tapply(ID_df1$output, ID_df1$IDS, function(x) x / sum(x)))
  }
)

# Unit: microseconds
#        expr       min        lq       mean     median         uq       max neval cld
#        orig 11936.111 12101.798 12705.9227 12310.2980 12914.0975 22949.662   100   c
#        tino  5224.230  5370.854  5636.8930  5558.3875  5734.9235  8466.684   100  b 
#  data.table   569.490   594.856   768.6615   724.4725   777.2565  3279.110   100 a  
#        base   497.937   524.623   606.8760   602.9200   650.2800  1933.098   100 a