gpt4 book ai didi

r - 在 R 中按组有效地存储数据

转载 作者:行者123 更新时间:2023-12-04 15:49:40 24 4
gpt4 key购买 nike

我有一个相对较大(约 250 万条记录)的数据框,结构大致如下:

df <- tibble(year = rep(2000:2009, times = 10), value = sample(0:1000, 100)) %>% 
arrange(year)

我想根据每年的分位数将每个值分配给一个桶(例如,观察值 1 在 2000 年的值的底部四分位数中)。对于我的简单示例,这很好用:

df %>% 
group_by(year) %>%
mutate(bucket = as.numeric(cut(value,
breaks = quantile(value, probs = c(0, .25, .5, .75, 1)),
include.lowest = T)))

df

# A tibble: 100 x 3
# Groups: year [10]
year value bucket
<int> <int> <dbl>
1 2000 281 1
2 2000 336 2
3 2000 873 4
4 2000 41 1
5 2000 335 1
6 2000 939 4
7 2000 746 3
8 2000 762 4
9 2000 345 2
10 2000 628 3

但在我的完整数据集上,这(不出所料)需要很长时间。为了加快速度,我在单独的数据框中计算了每年的分位数:

break_calc <- function(yr) {
library(magrittr)
df %>%
filter(year == yr) %$%
quantile(value, probs = c(0, .25, .5, .75, 1))
}

df_quants <- tibble(year = 2000:2009) %>%
mutate(breaks = map(year, ~break_calc(.x)))

但即便如此,我仍在努力想出一个不会永远耗费的解决方案。这对我的完整数据来说非常慢:

df %>% 
mutate(bucket = map2_dbl(value, year,
~cut(.x, breaks = unlist(df_quants$breaks[df_quants$year == .y]), include.lowest = T)))

这可能会快一点,但不是很好:

df %>% 
left_join(df_quants, by = "year") %>%
mutate(bucket = map2_dbl(value, breaks, ~cut(.x, breaks = unlist(.y), include.lowest = T)))

关于如何优化这个的任何想法?强烈倾向于将其保留在 dplyr/tidyverse 宇宙中,但如果它们有意义地更快,我愿意接受 apply/data.table 解决方案。

最佳答案

如何使用 dplyr 中的 data.table 和 ntile?

library(dplyr)
library(data.table)
df <- as.data.table(df)
df[, bucket:=ntile(value,4), by=year]

您也可以在代码中使用 ntile,但我发现 data.table 更快更干净

使用分位数:

library(dplyr) 
library(data.table)
df <- as.data.table(df)
df[, bucket:= as.integer(cut(value,
breaks = quantile(value, probs = c(0, .25, .5, .75, 1)),
include.lowest = T)), by=year]

关于r - 在 R 中按组有效地存储数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54336854/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com