使用dplyr对“非”分组数据进行汇总

3
我需要在分组的数据框中进行汇总(警告:dplyr解决方案非常受欢迎,但不是必需的),包括每个组的某些内容(简单)和“其他”组的相同内容。
最小示例
if(!require(pacman)) install.packages(pacman)
pacman::p_load(dplyr)

df <- data_frame(
    group = c('a', 'a', 'b', 'b', 'c', 'c'),
    value = c(1, 2, 3, 4, 5, 6)
)

res <- df %>%
    group_by(group) %>%
    summarize(
        median        = median(value)
#        median_other  = ... ??? ... # I need the median of all "other"
                                     # groups
#        median_before = ... ??? ... # I need the median of groups (e.g
                                 #    the "before" in alphabetic order,
                                 #    but clearly every roule which is
                                 #    a "selection function" depending
                                 #    on the actual group is fine)
    )

我期望的结果如下

group    median    median_other    median_before
  a        1.5         4.5               NA
  b        3.5         3.5               1.5
  c        5.5         2.5               2.5

我在谷歌上搜索了与"dplyr summarize excluding groups"和"dplyr summarize other then group"类似的字符串,我在dplyr文档中搜索,但没有找到解决方案。
这里(如何使用dplyr汇总值不匹配组)不适用,因为它只运行在sum上,即是一个"函数特定"的解决方案(还有一个简单的算术函数,没有考虑每个组的可变性)。对于更复杂的函数请求怎么办(例如mean、sd或用户函数)? :-)
感谢大家
注:summarize()是一个例子,同样的问题也适用于mutate()或其他基于组工作的dplyr函数。

你不能只使用 library(dplyr) 替代前两行代码吗? - Rich Scriven
如果您的系统中没有安装dplyr,那么使用library(dplyr)会返回错误。为了确保任何人都可以运行代码,我不得不写两行代码,而我决定使用pacman代替。在我看来,这是一个非常有用的包(因为您可以仅使用这两行代码加载(和安装,如果需要)多个包)。 - Corrado
2个回答

2

我认为在summarise()内不能对其他组执行操作是不可能的(也就是说,在汇总某个组时,其他组不可见)。你可以定义自己的函数并在mutate中使用它们来应用于特定变量。对于您的更新示例,您可以使用以下方法:

calc_med_other <- function(x) sapply(seq_along(x), function(i) median(x[-i]))
calc_med_before <- function(x) sapply(seq_along(x), function(i) ifelse(i == 1, NA, median(x[seq(i - 1)])))

df %>%
    group_by(group) %>%
    summarize(med = median(value)) %>%
    mutate(
        med_other = calc_med_other(med),
        med_before = calc_med_before(med)
    )
#   group   med med_other med_before
#   (chr) (dbl)     (dbl)      (dbl)
#1     a   1.5       4.5         NA
#2     b   3.5       3.5        1.5
#3     c   5.5       2.5        2.5

哦,这是一个非常好的解决方案(+1),但强调了误解(或我的示例中的错误解释)。即每个单独组都定义了最大值,max(max(group1), max(group2))等于max(union(group1, group2))...将max更改为mean或sd,可以(我希望)更准确地了解我的问题。(我“必须”使用“其他”组的所有信息来回答每一行) - Corrado
通过平均值,可以考虑到多样性并通过每个“其他”组的平均值和该组中元素的数量重新计算“其他”平均值。所以这是另一个不好的例子...也许中位数(或标准差,正如我刚才说的)可以是解决问题的好方法(如果有这样的解决方案)...它必须是“其他”组合集的函数,需要该集合的一些信息作为“单一”集合。 - Corrado
我刚刚编辑了问题,将最大值改为中位数。 - Corrado

2
这是我的解决方案:
res <- df %>%
  group_by(group) %>%
  summarise(med_group = median(value),
            med_other = (median(df$value[df$group != group]))) %>% 
  mutate(med_before = lag(med_group))

> res
Source: local data frame [3 x 4]

      group med_group med_other med_before
  (chr)     (dbl)     (dbl)      (dbl)
1     a       1.5       4.5         NA
2     b       3.5       3.5        1.5
3     c       5.5       2.5        3.5

我试图提供一个全 dplyr 的解决方案,但基于 R 的子集选取方法也可以很好地工作,median(df$value[df$group != group]) 返回所有不在当前组中的观测值的中位数。

希望这能帮助你解决问题。


抱歉回复晚了。这并没有对我有太大帮助:它取的是其他中位数的中位数,而不是其他值的中位数。所以问题仍然存在。 - Corrado
假设C组是C(5, 6, 7)。您的第一个med_other计算中位数(median(c(3, 4)), median(c(5, 6, 7))),这与median(3, 4, 5, 6, 7)不同。 - Corrado
@Corrado 我根据原始数据集(不包括当前组)调整了答案以计算 median_other 变量。 - donlelek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接