【问题标题】:Collapsing rows with dplyr使用 dplyr 折叠行
【发布时间】:2018-04-10 05:31:21
【问题描述】:

我是 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

我想根据以下条件汇总/折叠两行: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

提前谢谢你。

【问题讨论】:

  • 行没有完全折叠,它们被 2 2 2 折叠并且你没有解释规则,在你的真实数据中你真的有这样的 4 行序列吗?
  • @Moody_Mudskipper 如果列 A 中的值为 1 和 2,则行将被折叠。
  • 在生成随机数据时,在您的示例中包含 set.seed() 调用会很有帮助。这样其他人就可以完全复制您的结果!
  • 我读过这个,但它似乎可以由 4 人一组工作,这是假设选择的答案采取了,但在你的问题中没有明确

标签: r group-by dplyr summarize


【解决方案1】:

通过使隐含的、基于顺序的分组显式化,摘要可以 只需一个 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 %&gt;% select(-grp, -mean_grp).


PS。为了避免在代码中包含"magic numbers"(例如创建grp时的1:4each = 4),您还可以将第一个分组变量创建为:

grp = cumsum(A < lag(A, default = A[1])) + 1

假设原始数据的排序使得每次A 的值小于A 的先前值时都会启动一个新组。

【讨论】:

  • 我尝试运行代码,但收到此错误消息:Error in mutate_impl(.data, dots) : wrong result size (64), expected 16 or 1 我不确定为什么我们需要在第一个 group_by 函数中使用 each=4 参数。我还尝试通过省略 each=4 参数来运行代码,但输出没有排序。正如预期的那样。你能解释一下吗?
  • 啊,这是一个错字:一定是在做一些造型的时候把它留在里面了。您可以省略第一个 4,但您需要 each 将 4 个相邻行组合在一起。我已经进行了相应的编辑。
【解决方案2】:

一种选择是将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

【讨论】:

  • 谢谢@eipi10 我想知道如何保留行的顺序,以便可以按递增顺序排列行; 1.5, 3 ,4 ,1.5 3, 4, 1.5 3, 4, 1.5 3, 4.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-01
  • 2017-06-03
  • 1970-01-01
  • 2021-11-25
相关资源
最近更新 更多