聚合给定列上的数据框并显示另一列

jul*_*635 54 aggregate r plyr greatest-n-per-group

我在R中有以下形式的数据帧:

> head(data)
  Group Score Info
1     1     1    a
2     1     2    b
3     1     3    c
4     2     4    d
5     2     3    e
6     2     1    f
Run Code Online (Sandbox Code Playgroud)

我想在Score使用该max函数的列之后聚合它

> aggregate(data$Score, list(data$Group), max)

  Group.1         x
1       1         3
2       2         4
Run Code Online (Sandbox Code Playgroud)

但我还想显示与每个组InfoScore列的最大值相关联的列.我不知道该怎么做.我想要的输出是:

  Group.1         x        y
1       1         3        c
2       2         4        d
Run Code Online (Sandbox Code Playgroud)

任何提示?

Rei*_*son 51

基本R解决方案是将输出aggregate()merge()步骤组合.我发现公式接口aggregate()比标准接口更有用,部分原因是输出上的名称更好,所以我将使用它:

aggregate()一步是

maxs <- aggregate(Score ~ Group, data = dat, FUN = max)
Run Code Online (Sandbox Code Playgroud)

而这merge()一步很简单

merge(maxs, dat)
Run Code Online (Sandbox Code Playgroud)

这给了我们想要的输出:

R> maxs <- aggregate(Score ~ Group, data = dat, FUN = max)
R> merge(maxs, dat)
  Group Score Info
1     1     3    c
2     2     4    d
Run Code Online (Sandbox Code Playgroud)

当然,你可以把它固定在一个单行程中(中间步骤更多用于说明):

merge(aggregate(Score ~ Group, data = dat, FUN = max), dat)
Run Code Online (Sandbox Code Playgroud)

我使用公式接口的主要原因是它返回一个正确names的合并步骤的数据框; 这些是原始数据集中列的名称dat.我们需要输出aggregate()具有正确的名称,以便merge()知道原始数据帧和聚合数据帧中的哪些列匹配.

标准界面给出奇怪的名称,无论你怎么称呼它:

R> aggregate(dat$Score, list(dat$Group), max)
  Group.1 x
1       1 3
2       2 4
R> with(dat, aggregate(Score, list(Group), max))
  Group.1 x
1       1 3
2       2 4
Run Code Online (Sandbox Code Playgroud)

我们可以merge()在这些输出上使用,但是我们需要做更多的工作来告诉R哪些列匹配.


mbq*_*mbq 37

首先,使用split以下方法拆分数据:

split(z,z$Group)
Run Code Online (Sandbox Code Playgroud)

对于每个块,选择具有最大分数的行:

lapply(split(z,z$Group),function(chunk) chunk[which.max(chunk$Score),])
Run Code Online (Sandbox Code Playgroud)

最后减少回data.frame do.calling rbind:

do.call(rbind,lapply(split(z,z$Group),function(chunk) chunk[which.max(chunk$Score),]))
Run Code Online (Sandbox Code Playgroud)

结果:

  Group Score Info
1     1     3    c
2     2     4    d
Run Code Online (Sandbox Code Playgroud)

一行,没有魔法,快速,结果有好名字=)


And*_*rie 15

这是使用该plyr包的解决方案.

以下代码行基本上告诉ddply您首先按组对数据进行分组,然后在每个组中返回一个子集,其中Score等于该组中的最高分数.

library(plyr)
ddply(data, .(Group), function(x)x[x$Score==max(x$Score), ])

  Group Score Info
1     1     3    c
2     2     4    d
Run Code Online (Sandbox Code Playgroud)

而且,正如@SachaEpskamp指出的那样,这可以进一步简化为:

ddply(df, .(Group), function(x)x[which.max(x$Score), ])
Run Code Online (Sandbox Code Playgroud)

(which.max如果有的话,它还具有返回多个最大线的优点).


Sac*_*amp 5

plyr包可用于此目的。使用该ddply()函数,您可以在一个或多个列上拆分一个数据帧,并应用一个函数并返回一个数据帧,然后使用该函数,您可以将拆分后的数据帧summarize()的列用作变量以创建新的数据帧/;

dat <- read.table(textConnection('Group Score Info
1     1     1    a
2     1     2    b
3     1     3    c
4     2     4    d
5     2     3    e
6     2     1    f'))

library("plyr")

ddply(dat,.(Group),summarize,
    Max = max(Score),
    Info = Info[which.max(Score)])
  Group Max Info
1     1   3    c
2     2   4    d
Run Code Online (Sandbox Code Playgroud)


mne*_*nel 5

答案很晚,但是使用方法 data.table

library(data.table)
DT <- data.table(dat)

DT[, .SD[which.max(Score),], by = Group]
Run Code Online (Sandbox Code Playgroud)

或者,如果可能有多个相同的最高分数

DT[, .SD[which(Score == max(Score)),], by = Group]
Run Code Online (Sandbox Code Playgroud)

注意(从 ?data.table

.SD 是一个data.table,其中包含每个组(不包括组列)的x的数据子集


Dan*_*Dan 5

加文的答案是:合并之前,不使用公式接口时可以使用特定名称来聚合:

aggregate(data[,"score", drop=F], list(group=data$group), mean) 
Run Code Online (Sandbox Code Playgroud)