我有一个包含 >200,000 行和两列(组和值)的数据框。 Group 包含字符串,Value 包含正整数。所有行都是唯一的(即对于给定的组,每个值条目仅出现一次)。我想要
group_by(Group)
,然后确定某行的值与其他行值 ≤5 的实例数(参见示例)。
例如,如果某行具有组“A”且值为“25”,我们将搜索具有组“A”的所有行,以确定是否有任何行的值介于 20 和 30 之间。如果有任何此类行存在,将值 1 添加到组“A”的计数,然后继续到下一行。
我提供了一个只有 7 行的简化示例,以及一个使用
purr
来正确计算实例数量的代码。然而,当应用于 200,000 行的数据帧时,运行速度非常慢。
有没有一种方法可以减少计算负担?
data <- data.frame(Group = c("A", "A", "A", "B", "B", "B", "B"),
Value = c(1, 2, 3, 9, 15, 17, 19))
count_pairs <- function(positions) {
combn(positions, 2, function(x) abs(x[1] - x[2]) < 5) %>% sum
}
result <- data %>%
group_by(Group) %>%
summarise(Count = count_pairs(Value))
> print(result)
# A tibble: 2 × 2
Group Count
<chr> <int>
1 A 3
2 B 3
您希望将需要按组完成的操作与可以一次性在向量上完成的操作分开。这是使用 tidyverse 的示例。
library(tidyverse)
data <- tibble(
Group = c("A", "A", "A", "B", "B", "B", "B"),
Value = c(1, 2, 3, 9, 15, 17, 19)
)
data |>
arrange(Group, Value) |>
# Only do this part by group
mutate(value_prev = lag(Value),
value_next = lead(Value),
.by = Group) |>
# Vectorised operations for calculating the difference
mutate(prev_diff = Value - value_prev,
next_diff = value_next - Value,
min_diff = pmin(prev_diff, next_diff, na.rm = TRUE)) |>
filter(min_diff <= 5) |>
# Summarise by group again
summarise(Count = n(),
.by = Group)
# A tibble: 2 × 2
Group Count
<chr> <int>
1 A 3
2 B 3