按列中的相对差异分组(说明数据的排序方式)
Group by relative difference in a column (accounting for how data is ordered)
我有一个数据框。片段是:
df1 <- data.frame(x = c(1, 2, 1, 3, 5, 1, 4, 1), y = c(1, 1, 2, 2, 1, 1, 1, 3))
x y
1 1 1
2 2 1
3 1 2
4 3 2
5 5 1
6 1 1
7 4 1
8 1 3
我需要按 y
对 df1 进行分组并对 x
求和,但要考虑 y 的顺序。
即我需要在每个新 y
之后创建新组并对相应的 x
求和。
期望的输出是
x y
1 3 1
2 4 2
3 10 1
4 1 3
如何在 R 中执行此操作?
我们可以使用rleid
(来自data.table
)得到运行-length-id来对相邻的相似元素进行分组,得到[=25的sum
=]
library(dplyr)
library(data.table)
df1 %>%
group_by(grp= rleid(y), y) %>%
summarise(x = sum(x)) %>%
ungroup %>%
select(names(df1))
# A tibble: 4 x 2
# x y
# <dbl> <dbl>
#1 3 1
#2 4 2
#3 10 1
#4 1 3
或仅使用 dplyr
,用 'y' 的 lag
值创建一个逻辑表达式,在 group_by
中用 cumsum
转换为数字索引,然后得到 'x'
的 sum
df1 %>%
group_by(grp = cumsum(y != lag(y, default = first(y)))) %>%
summarise(x = sum(x), y = first(y)) %>%
select(-grp)
使用data.table
:
library(data.table)
setDT(df1)[, .(x=sum(x), y=y[1]), .(rleid(y))][,rleid:=NULL][]
#> x y
#> 1: 3 1
#> 2: 4 2
#> 3: 10 1
#> 4: 1 3
或使用 base::rle
的另一个 dplyr
解决方案:
library(dplyr)
df1 %>%
group_by(y_grp = with(rle(y), rep(seq_along(lengths), lengths))) %>%
summarise(x = sum(x), y = y[1]) %>%
ungroup %>% select(-y_grp)
#> # A tibble: 4 x 2
#> x y
#> <dbl> <dbl>
#> 1 3 1
#> 2 4 2
#> 3 10 1
#> 4 1 3
我有一个数据框。片段是:
df1 <- data.frame(x = c(1, 2, 1, 3, 5, 1, 4, 1), y = c(1, 1, 2, 2, 1, 1, 1, 3))
x y
1 1 1
2 2 1
3 1 2
4 3 2
5 5 1
6 1 1
7 4 1
8 1 3
我需要按 y
对 df1 进行分组并对 x
求和,但要考虑 y 的顺序。
即我需要在每个新 y
之后创建新组并对相应的 x
求和。
期望的输出是
x y
1 3 1
2 4 2
3 10 1
4 1 3
如何在 R 中执行此操作?
我们可以使用rleid
(来自data.table
)得到运行-length-id来对相邻的相似元素进行分组,得到[=25的sum
=]
library(dplyr)
library(data.table)
df1 %>%
group_by(grp= rleid(y), y) %>%
summarise(x = sum(x)) %>%
ungroup %>%
select(names(df1))
# A tibble: 4 x 2
# x y
# <dbl> <dbl>
#1 3 1
#2 4 2
#3 10 1
#4 1 3
或仅使用 dplyr
,用 'y' 的 lag
值创建一个逻辑表达式,在 group_by
中用 cumsum
转换为数字索引,然后得到 'x'
sum
df1 %>%
group_by(grp = cumsum(y != lag(y, default = first(y)))) %>%
summarise(x = sum(x), y = first(y)) %>%
select(-grp)
使用data.table
:
library(data.table)
setDT(df1)[, .(x=sum(x), y=y[1]), .(rleid(y))][,rleid:=NULL][]
#> x y
#> 1: 3 1
#> 2: 4 2
#> 3: 10 1
#> 4: 1 3
或使用 base::rle
的另一个 dplyr
解决方案:
library(dplyr)
df1 %>%
group_by(y_grp = with(rle(y), rep(seq_along(lengths), lengths))) %>%
summarise(x = sum(x), y = y[1]) %>%
ungroup %>% select(-y_grp)
#> # A tibble: 4 x 2
#> x y
#> <dbl> <dbl>
#> 1 3 1
#> 2 4 2
#> 3 10 1
#> 4 1 3