r - R&dplyr - 使用基于另一列的键的bin变量
问题描述
我正在尝试为下面的 data.frame 创建一个 bin 列df
,但 bin 将取决于该key
列。data.framelookup
包含每个键值的 bin 定义。
df <- data.frame(
key = c("foo", "bar"),
value = c(1, 10),
stringsAsFactors = FALSE
)
lookup <- data.frame(
foo = c(0, 5, 10),
bar = c(0, 12, 15),
stringsAsFactors = FALSE
)
bins <- df %>% rowwise() %>%
mutate(bin = as.numeric(cut(value, breaks = lookup %>% select(key) %>% pull, include.lowest = TRUE)))
上面的函数给出了预期的结果:
> bins
key value bin
1 foo 1 1
2 bar 10 1
但是,我实际使用的 data.frame 要大得多。该功能非常缓慢。有没有更好的方法来加快速度?
解决方案
一种选择是pmap
library(purrr)
library(dplyr)
pmap_dbl(df, ~ as.numeric(cut(..2, breaks = lookup[[..1]]))) %>%
mutate(df, bin = .)
# key value bin
#1 foo 1 1
#2 bar 10 1
基准
df1 <- df[rep(seq_len(nrow(df)), 1e4), ]
system.time({bins <- df1 %>%
rowwise() %>%
mutate(bin = as.numeric(cut(value,
breaks = lookup %>%
select(key) %>%
pull, include.lowest = TRUE)))})
# user system elapsed
# 25.907 0.120 25.914
system.time({bins2 <- pmap_dbl(df1, ~
as.numeric(cut(..2, breaks = lookup[[..1]]))) %>%
mutate(df1, bin = .)})
# user system elapsed
# 1.666 0.008 1.673
all.equal(bins, bins2)
#[1] TRUE