【问题标题】:findInterval by group with dplyr [duplicate]使用 dplyr 按组查找间隔 [重复]
【发布时间】:2021-08-04 10:52:33
【问题描述】:

在这个例子中,我有一个带有两个变量的小标题:

  • 组变量gr
  • 感兴趣的变量val
set.seed(123)
df <- tibble(gr = rep(1:3, each = 10), 
             val = gr + rnorm(30))

目标

我想使用函数findInterval 生成val 的离散化版本,但断点应该是gr 特定的,因为在我的实际数据以及本示例中,val 的分布取决于在gr。使用val 的四分位数在每个组内确定断点。

我做了什么

我首先构造一个嵌套的 tibble,其中包含 gr 的每个值的断点向量:

df_breakpoints <- bind_cols(gr = 1:3, 
                            purrr::map_dfr(1:3, function(gr) {
                              c(-Inf, quantile(df$val[df$gr == gr], c(0.25, 0.5, 0.75)), Inf)
                              })) %>% 
  nest(bp = -gr) %>% 
  mutate(bp = purrr::map(.$bp, unlist))

然后我和df一起加入:

df <- inner_join(df, df_breakpoints, by = "gr")

我对定义离散化变量lvl 的第一个猜测是

df %>% mutate(lvl = findInterval(x = val, vec = bp))

它会产生错误

Error : Problem with `mutate()` input `lvl2`.
x 'vec' must be sorted non-decreasingly and not contain NAs
ℹ Input `lvl` is `findInterval(x = val, vec = bp)`.

然后我尝试了

df$lvl <- purrr::imap_dbl(1:nrow(df),
                               ~findInterval(x = df$val[.x], vec = df$bp[[.x]]))

df %>% mutate(lvl = purrr::map2_int(df$val, df$bp, findInterval))

确实有效。然而,它是非常低效的。使用我的实际数据(120 万行)需要几分钟才能运行。我想有比在行上迭代更好的方法。有什么想法吗?

【问题讨论】:

标签: r dplyr


【解决方案1】:

您可以在group_by + mutate 步骤中执行此操作-

library(dplyr)

df %>%
  group_by(gr) %>%
  mutate(breakpoints = findInterval(val, 
                       c(-Inf, quantile(val, c(0.25, 0.5, 0.75)), Inf))) %>%
  ungroup

#      gr    val breakpoints
#   <int>  <dbl>       <int>
# 1     1  0.440           1
# 2     1  0.770           2
# 3     1  2.56            4
# 4     1  1.07            3
# 5     1  1.13            3
# 6     1  2.72            4
# 7     1  1.46            4
# 8     1 -0.265           1
# 9     1  0.313           1
#10     1  0.554           2
# … with 20 more rows

findInterval 分别应用于每个gr

【讨论】:

    猜你喜欢
    • 2018-10-08
    • 2021-12-07
    • 1970-01-01
    • 2015-03-30
    • 2023-01-10
    • 2017-04-11
    • 2017-10-27
    • 1970-01-01
    • 2020-08-09
    相关资源
    最近更新 更多