2015-05-18 125 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