我正在处理大型行(最少8百万行)dataframes
,并且希望基于几个分组变量和rmultinom
进行一些基本计算。就我的代码而言,至少需要大约1秒钟才能完成计算,这不是问题,但是我需要做数千次,所以我真的想加快速度。
我目前正在使用dataframes
和tidyverse
,但我并不局限于这两个。我尝试使用data.table
来实现,但无法弄清楚。关于如何加快速度的任何建议将不胜感激。
一个例子(真实数据可以大于或等于一个数量级):
library(tidyverse)
library(microbenchmark)
# create dummy data
df <- data.frame(fact = rep(letters, each = 312000),
month = rep(month.name, 26),
num = rep(sample(10000:100000, 12), 26),
prob = runif(312))
# Order by month
df <- df[order(df$month), ]
# group by two factor variables and calculate new variable
microbenchmark({
df2 <- df %>%
group_by(fact, month) %>%
mutate(res = ifelse(prob > 0, c(rmultinom(1, num[1], prob = prob)), 0))}, times = 10)
> Unit: milliseconds
> min lq mean median uq max neval
> 816.3126 822.4083 840.7966 834.6163 855.5139 879.9345 10
答案 0 :(得分:4)
评论太久了,所以我在这里发表。
运行
library(profr)
plot(profr(
df %>% group_by(fact, month) %>%
mutate(res = ifelse(prob > 0, c(rmultinom(1, num[1], prob = prob)), 0))
))
我得到以下信息:
因此,您似乎真的想为multinom
找到一个更快的实现,这似乎是瓶颈。 dplyr
和data.table
的瓶颈相同,这意味着仅加速rmultinorm
会大大提高速度。
答案 1 :(得分:1)
使用data.table,您可以这样做:
dt <- copy(df)
setDT(dt)
dt[, res := 0L][prob > 0, res := c(rmultinom(1, num[1], prob = prob)), by = .(fact, month)]
这会给您带来轻微的速度改进:
microbenchmark(dp = df %>%
group_by(fact, month) %>%
mutate(res = ifelse(prob > 0, c(rmultinom(1, num[1], prob = prob)), 0)),
dt = dt[, res := 0L][prob > 0, res := c(rmultinom(1, num[1], prob = prob)), by = .(fact, month)],
times = 1)
Unit: seconds expr min lq mean median uq max neval dp 1.356745 1.356745 1.356745 1.356745 1.356745 1.356745 1 dt 1.063363 1.063363 1.063363 1.063363 1.063363 1.063363 1
答案 2 :(得分:1)