2014-11-06 67 views
1

我有如下表:條件列計算最大值

Class x2 x3 x4 
    A 14 45 53 
    A  8 18 17 
    A 16 49 20 
    B 78 21 48 
    B  8 18 5 

我需要爲每個「類」(A和B)找到列「X3」的最大值,保留該行並刪除其他行。

輸出應該在這樣的格式:

Class x2 x3 x4 
    A 14 49 20 
    B 78 21 48 

請,問我在我的問題的問題,如果有不清楚的。

謝謝!使用dplyr

+0

您在預計結果的情況下會有什麼結果?即如果在第x3欄中第一個和第三個條目都是49? – 2014-11-06 07:11:13

回答

4

一個基礎R的做法可能是:

mydf[as.logical(with(mydf, ave(x3, Class, FUN = function(x) x == max(x)))), ] 
# Class x2 x3 x4 
# 3  A 16 49 20 
# 4  B 78 21 48 

但請注意,如果有並列爲max多個值,它將返回多行該組。


這裏是一個可能的 「data.table」 的方法:

library(data.table) 
setkey(as.data.table(mydf), Class, x3)[, tail(.SD, 1), by = Class] 
# Class x2 x3 x4 
# 1:  A 16 49 20 
# 2:  B 78 21 48 
+0

考慮到綁定的最大值是很好的。非常周到。 +1 :) – jazzurro 2014-11-06 03:54:36

+0

@jazzurro,但這個問題沒有提供足夠的信息來說明這是否合意或不合適:-) – A5C1D2H2I1M1N2O1R2T1 2014-11-06 04:07:20

+0

很好考慮這種可能性。 – jazzurro 2014-11-06 04:10:10

2

方式一:

library(dplyr) 

foo %>% 
    #For each Class 
    group_by(Class) %>% 
    # Sort rows in descending way using x3: you get the max x3 value on top 
    # for each group 
    arrange(desc(x3)) %>% 
    # Select the first row for each Class 
    slice(1) 

# Class x2 x3 x4 
#1  A 16 49 20 
#2  B 78 21 48 

編輯 鑑於@阿南達的領帶值考慮,他在評析的建議, 你可以做這樣的事情爲好。但是,@理查德·阿克爾文的想法是,如果有聯繫的話,那麼這條路就是 。

# Data 
foo2 <- structure(list(Class = structure(c(1L, 1L, 1L, 2L, 2L), .Label = c("A", 
"B"), class = "factor"), x2 = c(14L, 8L, 16L, 78L, 8L), x3 = c(49L, 
18L, 49L, 21L, 18L), x4 = c(53L, 17L, 20L, 48L, 5L)), .Names = c("Class", 
"x2", "x3", "x4"), class = "data.frame", row.names = c(NA, -5L 
)) 

# Class x2 x3 x4 
#1  A 14 49 53 
#2  A 8 18 17 
#3  A 16 49 20 
#4  B 78 21 48 
#5  B 8 18 5 

foo2 %>% 
    group_by(Class) %>% 
    mutate(Rank = dense_rank(desc(x3))) %>% 
    filter(Rank == 1) 

# Class x2 x3 x4 Rank 
#1  A 14 49 53 1 
#2  A 16 49 20 1 
#3  B 78 21 48 1 
+0

+1。我不會使用「dplyr」,但「切片」似乎可以解決問題。 – A5C1D2H2I1M1N2O1R2T1 2014-11-06 03:57:17

+0

@AnandaMahto如果'切片'可以打領帶,那就太好了。 – jazzurro 2014-11-06 04:08:11

+0

「dplyr」有非常好的'rank'選項,在這裏可能很有用。 – A5C1D2H2I1M1N2O1R2T1 2014-11-06 04:09:01

2

這裏的另一個dplyr回答了很多

library(dplyr) 
df %>% group_by(Class) %>% filter(x3 == max(x3)) 
# Source: local data frame [2 x 4] 
# Groups: Class 
# 
# Class x2 x3 x4 
# 1  A 16 49 20 
# 2  B 78 21 48 

這也可能是

group_by(df, Class) %>% filter(x3 == max(x3)) 
+0

這樣,你不需要'dense_rank'。你的第一個dplyr答案? +1 :) – jazzurro 2014-11-06 05:05:35

+1

我的第二。第一個投了票,我刪除了它。哈哈。我決定學會更多地使用'dplyr'。我非常喜歡這種管道材料。代碼非常乾淨。 – 2014-11-06 05:06:38

+1

我們都是這樣的,不是嗎?犯錯誤並學習更多!我有一天誤解了一個有關字符串的問題,並被壓低了;我立即道歉並刪除了我的答案。 – jazzurro 2014-11-06 05:14:59

0

嘗試:

do.call(rbind, lapply(split(ddf, ddf$Class), function(x) tail(x[order(x$x3),],1))) 
    Class x2 x3 x4 
A  A 16 49 20 
B  B 78 21 48