2015-05-18 88 views
4

我想通过一个因素使数据框的最大超过记录。我想要一个有4行(每个G有一个)的数据框,该组中的X的最大值和相应的Y值。我知道我可以写一个循环,但宁可不要。R功能which.max与tapply

Data<-data.frame(X=rnorm(200), Y=rnorm(200), G=rep(c(1,2,3,4), each=50)) 
XMax<-tapply(Data$X, Data$G, function(x){max(x, na.rm=T)}) 
WhichXMax<-tapply(Data$X, Data$G, function(x){which.max(x)}) 

的which.max函数返回的行数的数据已经被tapply因素,在这里我真正想要的行号引用数据子集行之后。所以我可以做一些事情;

YMax<-Data$Y[Which] 
MaxData<-data.frame(XMax=XMax, YMax=YMax, G=levels(Data$G)) 

回答

6

您可以使用bywhich.max引用返回该行的rownames

Data[by(Data, Data$G, function(dat) rownames(dat)[which.max(dat$X)]),] 

#   X   Y G 
#4 1.595281 -0.3309078 1 
#61 2.401618 0.9510128 2 
#147 2.087167 0.9160193 3 
#171 2.307978 -0.3887222 4 

(为了可重复性,假定set.seed(1)

7
library(dplyr) 
Data %>% 
    group_by(G) %>% 
    filter(X==max(X)) 

如果你不想包括领带,然后

Data %>% 
    group_by(G) %>% 
    arrange(desc(X)) %>% 
    slice(1) 
+0

我在我的'真实数据'上试过这段代码,它给了我6行以上的长度(level(Data $ G))任何想法?它看起来像报道两个行,如果有领带?而接受的答案只是为领带选择一个。你也可以解释一下操作%<%,我以前没有看到过! :) – LoveMeow

5
library(data.table) 
    set.seed(1) 
    Data<-data.frame(X=rnorm(200), Y=rnorm(200), G=rep(c(1,2,3,4), each=50)) 
    setDT(Data)[,list(X=max(X),Y=Y[which.max(X)]),by=G] 
    G  X   Y 
1: 1 1.595281 -0.3309078 
2: 2 2.401618 0.9510128 
3: 3 2.087167 0.9160193 
4: 4 2.307978 -0.3887222 
+4

简单:'setDT(Data)[,. SD [which.max(X)],by = G]' – Frank