为什么 slice_min() 慢?

问题描述 投票:0回答:1

考虑一个带有

dat
变量的数据框
group
,并且每组有一个或多个
x
观察值。假设组内
x
中没有关系。提取使每个
x
内的
group
最小化的观察结果的一种方法是使用
dplyr::slice_min()

我喜欢

slice_min()
清楚地表达了我的意图,但它通常很慢,如下所示。在组内排列
x
的值时,我预计性能会较慢(比查找最小值更简单)。怎么速度这么快?即使我奇怪地使用下面的
summarize()
也快得多!

更具体地说,我希望在 n 个组和每组 O(1) 次观察中保持良好的性能,因为 n 趋于无穷大。

library(dplyr)
library(microbenchmark)

# Simulate data. y is some other variable whose value we'd like to keep at the
# minimum of x.
set.seed(1)
n <- 5e3
k <- 1 + rpois(n, 1)
dat <- data.frame(
  group = rep(1:n, k), 
  x = rnorm(sum(k)),
  y = sample(letters, sum(k), replace = TRUE)
)

# Obtain observation that minimizes x within each group
microbenchmark(
  slice = dat |> 
    group_by(group) |> 
    slice_min(x) |> 
    ungroup(),
  arrange = dat |> 
    arrange(group, x) |> 
    filter(!duplicated(group)),
  summarize = dat |> 
    group_by(group) |> 
    summarize(i = which.min(x), across(everything(), \(v) v[i])) |> 
    select(!i),
  times = 10
)

性能:

# Unit: milliseconds
#       expr        min         lq       mean    median         uq        max neval
#      slice 556.812802 625.876500 655.172451 632.45395 646.751201 909.931001    10
#    arrange   3.148302   3.209201   3.348941   3.34970   3.441501   3.663301    10
#  summarize  37.503501  37.946201  53.125181  38.17705  38.911001 127.843800    10
r dataframe sorting dplyr
1个回答
0
投票

与 slice_max 相关的 github 问题有一位

dplyr
的作者建议对
arrange
方法进行变体,甚至更快: https://github.com/tidyverse/dplyr/issues/6783

 arrange2 = dat |> 
    arrange(x) |>
    distinct(group)
© www.soinside.com 2019 - 2024. All rights reserved.