分组/汇总时如何保留列?

问题描述 投票:0回答:6

所以,这个问题的问题是,我无法发布实际的代码,因为我必须签署一份协议,而且我是 R 的新手,可能无法很好地解释这一点,但也许有人可以帮助我......

假设我有一些数据:

A   B    C   D
F1  6.6  10  10
F1  3.1  10  10
A1  1.0  20  10
B1  3.4  20  20

因此,对于每个 A,C 和 D 值是相同的。 但我想使用 dplyr 来找到 Bmean,如下所示:

A    Bmean   C    D
F1   4,85    10  10
A1   1.0     20  10
B1   3.4     20  20

我该怎么做?我的想法是使用类似的东西

dplyr::group_by(A) %>% dplyr::summarize(Bmean = mean(B))

但是C和D似乎在这个操作之后消失了。 对我想保留的所有列进行 group_by 有意义吗? 或者说这会如何运作?

为了澄清,我想使用 dplyr 语法,因为如果可能的话,它是更大操作的一部分。

r dplyr
6个回答
6
投票

我想添加一个 awnser 来专门解决使用 dplyr 的问题。虽然我确信,有更优雅的方法可以做到这一点,但以下建议可以在汇总/聚合数据框中保留具有附加描述性变量的列。此外,如果不是这种情况,代码将无法保护您免受更大数据帧中的错误。

library(dplyr)
library(tibble)

df <- tribble(
  ~A  , ~B , ~c , ~D ,
  "F1", 6.6, 10 , 10 ,
  "F1", 3.1, 10 , 10 ,
  "A1", 1.0, 20 , 10 ,
  "B1", 3.4, 20 , 20
)

以下代码删除 C 列和 D 列

df %>%
  group_by(A) %>%
  summarise(Bmean = mean(B)) 

此代码保留 C 列和 D 列。请注意,只有在组的每一行中都有相同的变量时,这才有效。但由于变量应该被保留并且不会对分组行为产生影响,所以无论如何都应该如此。

df %>%
  group_by(A) %>%
  summarise(Bmean = mean(B),
            C = unique(C),
            D = unique(D))

更新:

事实上,如果分组级别不“小于”分组变量,您还可以将组包含在 group_by 表达式中

Group1:
  A ,  B ,  C ,  D
"F1", 6.6, 10 , 10 
"F1", 3.1, 10 , 10 
Group2:
"A1", 1.0, 20 , 10 
Group3:
"B1", 3.4, 20 , 20

请注意,C 列和 D 列在每组内保持相同的值。 这意味着它们可以安全地用在分组表达式中,因此可以 保留。

所以在你的情况下这也行得通:

group_by(A,C,D)

5
投票

好吧,这个问题有点老了,但万一有人仍然像我一样最终来到这里,这里有一个具有相同包(dplyr)的解决方案。如果您有许多列需要保持不变,则效果特别好。

df %>%
  group_by(A) %>%
  summarise(Bmean = mean(B),
            across(C:D, .fns = ~.x))

它将一个函数(不执行任何操作)应用于 C 到 D 列(注意:我在这里使用大写“C”,而不是原始帖子中的小写“c”)


4
投票

您可以使用

base R

来完成此操作
aggregate(data=df1,B~.,FUN = mean)

3
投票

你可以简单地使用这样的东西:

aggregate(cbind(B, C, D) ~ A, df, mean)

这里 df 是包含 A、B、C 和 D 列的数据框。


3
投票

我们可以使用

data.table

library(data.table)
setDT(df1)[,.(Bmean = mean(B)) , .(A, C, D)]
#     A  C  D Bmean
#1: F1 10 10  4.85
#2: A1 20 10  1.00
#3: B1 20 20  3.40

0
投票

随着

dplyr
版本比 1.1.0 更新,引入了一个名为
reframe()
的新函数,但仍标记为 实验性

回答这个问题,

reframe()
可能会有所帮助,如以下代码片段:

tibble::tribble(
    ~A,    ~B,  ~C, ~D,
    "F1",  6.6, 10, 10,
    "F1",  3.1, 10, 10,
    "A1",  1.0, 20, 10,
    "B1",  3.4, 20, 20,
) |> dplyr::group_by(A) |> 
  dplyr::reframe(
    Bmean = mean(B),
    dplyr::across(C:D),
  )
© www.soinside.com 2019 - 2024. All rights reserved.