使用 dplyr 折叠行
Collapsing rows with dplyr
我是 R 的新手,正在尝试使用 dplyr 根据行值折叠行。以下示例显示示例数据。
set.seed(123)
df<-data.frame(A=c(rep(1:4,4)),
B=runif(16,min=0,max=1),
C=rnorm(16, mean=1,sd=0.5))
A B c
1 1 0.36647435 0.7485365
2 2 0.51864614 0.8654337
3 3 0.04596929 0.9858012
4 4 0.15479619 1.1294208
5 1 0.76712372 1.2460700
6 2 0.17666676 0.7402996
7 3 0.89759874 1.2699954
8 4 0.90267735 0.7101804
9 1 0.91744223 0.3451281
10 2 0.25472599 0.8604743
11 3 0.10933985 0.8696796
12 4 0.71656017 1.2648846
13 1 0.21157810 1.3170205
14 2 0.14947268 1.2789700
15 3 0.92251060 1.5696901
16 4 0.30090579 1.7642853
我想 summarize/collapse 两行,条件是 A
列中值为 1 和 2 的行作为一行(作为第 1 行和第 2 行的平均值)。因此最终结果将只有 12 行,因为其他 4 行已被折叠。
我尝试使用以下 dplyr
函数,但收效甚微。
install.packages ("tidyverse")
图书馆 (tidyverse)
df %>% summarize_each( fun(i){ for i %in% c(1,2)funs(mean) })
预期输出类似于:
A B C
1 1.5 0.4425602 0.8069851
3 3 0.04596929 0.9858012
4 4 0.15479619 1.1294208
5 1.5 0.4718952 0.9931848
7 3 0.89759874 1.2699954
8 4 0.90267735 0.7101804
9 1.5 0.5860841 0.6028012
11 3 0.10933985 0.8696796
12 4 0.71656017 1.2648846
13 1.5 0.1805254 1.297995
15 3 0.92251060 1.5696901
16 4 0.30090579 1.7642853
提前致谢。
一个选项是将 A
等于 1 或 2 的行与其他行分开处理,然后将它们重新绑定在一起:
set.seed(3)
df<-data.frame(A=c(rep(1:4,4)),B=runif(16,min=0,max=1),c=rnorm(16, mean=1,sd=0.5))
df %>%
filter(A %in% 1:2) %>%
group_by(tmp=cumsum(A==1)) %>%
summarise_all(mean) %>%
ungroup %>% select(-tmp) %>%
bind_rows(df %>% filter(!A %in% 1:2))
A B c
<dbl> <dbl> <dbl>
1 1.5 0.4877790 1.0121278
2 1.5 0.6032474 0.8840735
3 1.5 0.6042946 0.5996850
4 1.5 0.5456424 0.6198039
5 3.0 0.3849424 0.6276092
6 4.0 0.3277343 0.4343907
7 3.0 0.1246334 1.0760229
8 4.0 0.2946009 0.8461718
9 3.0 0.5120159 1.6121568
10 4.0 0.5050239 1.0999058
11 3.0 0.8679195 0.8981359
12 4.0 0.8297087 0.1667626
通过使隐式的、基于顺序的分组显式化,摘要可以
只需一次 summarise_all
调用即可完成。
# Generate the data
set.seed(1)
df <- data.frame(
A = c(rep(1:4, 4)),
B = runif(16, min = 0, max = 1),
C = rnorm(16, mean = 1, sd = 0.5)
)
library(dplyr)
new <- df %>%
group_by(grp = rep(
1:4, # vector containing names of groups to create
each = 4 # number of elements in each group
)) %>%
group_by(mean_grp = cumsum(A > 2) + 1, add = T) %>%
summarise_all(mean) %>%
ungroup()
new
#> # A tibble: 12 x 5
#> grp mean_grp A B C
#> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 1 1 1.5 0.3188163 1.067598241
#> 2 1 2 3.0 0.5728534 1.755890584
#> 3 1 3 4.0 0.9082078 1.194921618
#> 4 2 1 1.5 0.5500358 0.291014883
#> 5 2 2 3.0 0.9446753 1.562465459
#> 6 2 3 4.0 0.6607978 0.977533195
#> 7 3 1 1.5 0.3454502 1.231911487
#> 8 3 2 3.0 0.2059746 1.410610598
#> 9 3 3 4.0 0.1765568 1.296950661
#> 10 4 1 1.5 0.5355633 1.425278418
#> 11 4 2 3.0 0.7698414 1.037282492
#> 12 4 3 4.0 0.4976992 0.005324152
我建议在
总结(如果你把它们放在首位,一切都会更简单),
但如果你愿意,你可以用
new %>% select(-grp, -mean_grp)
.
PS。为了避免在代码中包含"magic numbers"(例如创建grp
时的1:4
和each = 4
),您还可以创建第一个分组变量:
grp = cumsum(A < lag(A, default = A[1])) + 1
假设原始数据是这样排序的,每次 A
的值小于 A
的前一个值时,一个新的组开始。
我是 R 的新手,正在尝试使用 dplyr 根据行值折叠行。以下示例显示示例数据。
set.seed(123)
df<-data.frame(A=c(rep(1:4,4)),
B=runif(16,min=0,max=1),
C=rnorm(16, mean=1,sd=0.5))
A B c
1 1 0.36647435 0.7485365
2 2 0.51864614 0.8654337
3 3 0.04596929 0.9858012
4 4 0.15479619 1.1294208
5 1 0.76712372 1.2460700
6 2 0.17666676 0.7402996
7 3 0.89759874 1.2699954
8 4 0.90267735 0.7101804
9 1 0.91744223 0.3451281
10 2 0.25472599 0.8604743
11 3 0.10933985 0.8696796
12 4 0.71656017 1.2648846
13 1 0.21157810 1.3170205
14 2 0.14947268 1.2789700
15 3 0.92251060 1.5696901
16 4 0.30090579 1.7642853
我想 summarize/collapse 两行,条件是 A
列中值为 1 和 2 的行作为一行(作为第 1 行和第 2 行的平均值)。因此最终结果将只有 12 行,因为其他 4 行已被折叠。
我尝试使用以下 dplyr
函数,但收效甚微。
install.packages ("tidyverse") 图书馆 (tidyverse)
df %>% summarize_each( fun(i){ for i %in% c(1,2)funs(mean) })
预期输出类似于:
A B C
1 1.5 0.4425602 0.8069851
3 3 0.04596929 0.9858012
4 4 0.15479619 1.1294208
5 1.5 0.4718952 0.9931848
7 3 0.89759874 1.2699954
8 4 0.90267735 0.7101804
9 1.5 0.5860841 0.6028012
11 3 0.10933985 0.8696796
12 4 0.71656017 1.2648846
13 1.5 0.1805254 1.297995
15 3 0.92251060 1.5696901
16 4 0.30090579 1.7642853
提前致谢。
一个选项是将 A
等于 1 或 2 的行与其他行分开处理,然后将它们重新绑定在一起:
set.seed(3)
df<-data.frame(A=c(rep(1:4,4)),B=runif(16,min=0,max=1),c=rnorm(16, mean=1,sd=0.5))
df %>%
filter(A %in% 1:2) %>%
group_by(tmp=cumsum(A==1)) %>%
summarise_all(mean) %>%
ungroup %>% select(-tmp) %>%
bind_rows(df %>% filter(!A %in% 1:2))
A B c <dbl> <dbl> <dbl> 1 1.5 0.4877790 1.0121278 2 1.5 0.6032474 0.8840735 3 1.5 0.6042946 0.5996850 4 1.5 0.5456424 0.6198039 5 3.0 0.3849424 0.6276092 6 4.0 0.3277343 0.4343907 7 3.0 0.1246334 1.0760229 8 4.0 0.2946009 0.8461718 9 3.0 0.5120159 1.6121568 10 4.0 0.5050239 1.0999058 11 3.0 0.8679195 0.8981359 12 4.0 0.8297087 0.1667626
通过使隐式的、基于顺序的分组显式化,摘要可以
只需一次 summarise_all
调用即可完成。
# Generate the data
set.seed(1)
df <- data.frame(
A = c(rep(1:4, 4)),
B = runif(16, min = 0, max = 1),
C = rnorm(16, mean = 1, sd = 0.5)
)
library(dplyr)
new <- df %>%
group_by(grp = rep(
1:4, # vector containing names of groups to create
each = 4 # number of elements in each group
)) %>%
group_by(mean_grp = cumsum(A > 2) + 1, add = T) %>%
summarise_all(mean) %>%
ungroup()
new
#> # A tibble: 12 x 5
#> grp mean_grp A B C
#> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 1 1 1.5 0.3188163 1.067598241
#> 2 1 2 3.0 0.5728534 1.755890584
#> 3 1 3 4.0 0.9082078 1.194921618
#> 4 2 1 1.5 0.5500358 0.291014883
#> 5 2 2 3.0 0.9446753 1.562465459
#> 6 2 3 4.0 0.6607978 0.977533195
#> 7 3 1 1.5 0.3454502 1.231911487
#> 8 3 2 3.0 0.2059746 1.410610598
#> 9 3 3 4.0 0.1765568 1.296950661
#> 10 4 1 1.5 0.5355633 1.425278418
#> 11 4 2 3.0 0.7698414 1.037282492
#> 12 4 3 4.0 0.4976992 0.005324152
我建议在
总结(如果你把它们放在首位,一切都会更简单),
但如果你愿意,你可以用
new %>% select(-grp, -mean_grp)
.
PS。为了避免在代码中包含"magic numbers"(例如创建grp
时的1:4
和each = 4
),您还可以创建第一个分组变量:
grp = cumsum(A < lag(A, default = A[1])) + 1
假设原始数据是这样排序的,每次 A
的值小于 A
的前一个值时,一个新的组开始。