R - 根据第3列的统计信息,按另一列汇总1列的数据

时间:2014-02-19 12:32:05

标签: r aggregate

假设我有一个R数据框,包含3列 A B C ,其中 A 价值观并非完全不同。

如何获取A的所有值,B的值最小为C(对于A的值)? 类似于伪SQL代码:SELECT C WHERE B = MIN(B) GROUPBY A

我查看了aggregate()函数,但我不确定它是否可以完成。

aggregate(B ~ A, data = mydataframe, min)只给出了每个A的B的最小值,但后来我不知道如何得到相应的C值。

是否有办法使用此聚合的结果对数据框进行子集以获取C值,和/或是否可以仅在aggregate()的一次调用中完成?

由于

我想得到的一个例子:

输入:

A   B   C
1   0   1
1   2   2
1   1   3
1   1   4
2   1   1
2   2   2
2   0   3
2   3   4

输出:

1
3

1是对应于A = 1

的B(0)的最小值的C的值

3是对应于A = 2

的B(0)的最小值的C的值

3 个答案:

答案 0 :(得分:4)

您可以使用data.table包:

library(data.table)
DT <- as.data.table(mydataframe)

DT[ , C[which.min(B)], by = "A"]
#    A V1
# 1: 1  1
# 2: 2  3

dplyr

library(dplyr)
mydataframe %.%
  group_by(A) %.%
  summarise(res = C[which.min(B)])
#   A res
# 1 2   3
# 2 1   1

或基本功能by

by(mydataframe, mydataframe$A, function(x) x$C[which.min(x$B)])
# mydataframe$A: 1
# [1] 1
# -------------------------------------------------------------------------------
# mydataframe$A: 2
# [1] 3

答案 1 :(得分:4)

1) SQLite保证当您使用minmax时,其他列变量将来自同一行,因此我们得到一个特别简单的解决方案:

library(sqldf)

# one minimum per group
sqldf("select A, min(B) B, C from DF group by A")

如果可能存在重复的最小值并且我们想要所有这些,那么使用correlated subquery进行选择就可以了:

# all minima per group
sqldf("select * from DF x 
      where x.b = (select min(y.b) from DF y where y.a = x.a)")

2)在R的基础上使用ave我们可以这样做:

# one minimum per group
subset(DF, !! ave(B, A, FUN = function(x) seq_along(x) == which.min(x)))

# all minima per group
subset(DF, !! ave(B, A, FUN = function(x) x == min(x)))

3)如果您确实想使用aggregate,请执行以下操作:

# one minimum per group
sq <- 1:nrow(DF)
DF[aggregate(sq ~ A, DF, function(ix) ix[which.min(DF$B[ix])])$sq, ]

答案 2 :(得分:3)

您可以对A和B列上的表进行排序:

d<-structure(list(A = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), B = c(0L, 
2L, 1L, 1L, 1L, 2L, 0L, 3L), C = c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 
4L)), .Names = c("A", "B", "C"), class = "data.frame", row.names = c(NA, 
-8L))
d2<-d[order(d$A, d$B),]

数据框d2应如下所示:

  A B C
1 1 0 1
3 1 1 3
4 1 1 4
2 1 2 2
7 2 0 3
5 2 1 1
6 2 2 2
8 2 3 4

由于在排序数据帧中,B的值在A的每个值内都按升序排列,因此每个不同A值的第一行是对应于B的最小值的那一行。

然后,使用函数duplicated()和通常的下标,删除A中没有重复的所有行,并仅返回C中的值(第三列):

d2[!duplicated(d2$A),3]
[1] 1 3
相关问题