2014-02-19 34 views
5

比方说,我有3列Ç,凡值是R数据帧并非全部不同。的R - 用于通过另一列1列聚集数据,基于statistices上的第三列

我该如何获得A的所有值,即B的最小值(对于A的值)的C值? 类似于伪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是对应于最小的valueOfÇ对于A = 1,B(0)0

3是C的对应于最小B的值(0)为A = 2

+3

欢迎使用Stack溢出。你能提供一些数据来测试它吗?用'head(my_data)'做就行了。同样,如果你发布你想要的输出,它会使其重现。 – Llopis

+2

谢谢我用一个例子编辑了这篇文章。 –

回答

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 
+0

谢谢,data.table解决方案非常好(而且速度很快)!对于我的理解,我试图让总合作,开发基于您的解决方案,你有什么想法,为什么下面不工作? :aggregate(cbind(B,C)〜A,data = mydataframe,function(x,y)y [which.min(x)] –

+0

@JeanpierreNenuphar由于'aggregate'中的函数被应用,此命令不起作用到所有列*单独*。 –

+0

有谁知道为什么data.tables版本并不在一个包/工作如何让data.tables一个包中的工作吗? – Sean1708

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()和通常的标,除去未所述的复制的所有行,并选自C只返回值(第三列):

d2[!duplicated(d2$A),3] 
[1] 1 3 
3

1) SQLite的保证,当你使用minmax另一列变量将来自同一行,所以我们得到一个特别简单的解决方案:

library(sqldf) 

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

如果可以有duplica泰德极小,我们希望所有的人都那么这个选择使用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, ] 
相关问题