#r #dplyr #merge #cumsum
Вопрос:
Я спрашиваю, как объединить близкие значения (mz) в столбце (разница меньше 20), сгруппировать столбец mz и затем вычислить среднее значение? для примера.
mz1 <- c(seq(100, 190, by = 10))
rt1 <- c(seq(1, 10, by = 1))
value1 <- runif(10, min = 100, max = 100000)
df1 <- as.data.frame(cbind(mz1, rt1, value1))
Я хотел бы получить такой результат, как:
raw data
1 100 1 14365.72
2 110 2 41513.18
3 120 3 41431.06
4 130 4 36947.66
5 140 5 15329.23
6 150 6 13966.73
7 160 7 23380.11
8 170 8 46649.65
9 180 9 26670.67
10 190 10 85796.99
output
1 100 1 14365.72
2 110 1 41513.18
3 120 1 41431.06
4 130 2 36947.66
5 140 2 15329.23
6 150 2 13966.73
7 160 3 23380.11
8 170 3 46649.65
9 180 3 26670.67
10 190 4 85796.99
Я могу использовать информацию о подгруппах для вычисления среднего значения, но я не знаю, как сгруппировать столбец mz в соответствии со значением отсечения (20 или другие).
Спасибо хеми
Ответ №1:
Я думаю, тебе это нужно. Создайте новый вектор в нужной последовательности, например mz
, через accumulate
, который не заменяет значение, если оно не увеличено на N
. После dense_rank
этого был использован. Вы можете безопасно использовать data.table::rleid
вместо dense_rank
, если случайно вы можете получить повторяющиеся значения.
set.seed(123)
mz1 <- c(seq(100, 190, by = 10))
rt1 <- c(seq(1, 10, by = 1))
value1 <- runif(10, min = 100, max = 100000)
df1 <- as.data.frame(cbind(mz1, rt1, value1))
library(tidyverse)
N <- 20
df1 %>%
mutate(sub_grp = dense_rank(accumulate(mz1, ~if(abs(.x - .y) > N) {.y} else .x)))
#> mz1 rt1 value1 sub_grp
#> 1 100 1 28828.994 1
#> 2 110 2 78851.683 1
#> 3 120 3 40956.794 1
#> 4 130 4 88313.439 2
#> 5 140 5 94052.682 2
#> 6 150 6 4651.094 2
#> 7 160 7 52857.738 3
#> 8 170 8 89252.663 3
#> 9 180 9 55188.358 3
#> 10 190 10 45715.812 4
Создано 2021-06-09 пакетом reprex (v2.0.0)