2015-07-03 49 views
2

我有一個包含兩列的日期框架。我想刪除第一列中有重複條目的行。不過,我想選擇一個特定的行保持基於第二列的值。按R中的中值摺疊重複行

具體 - 如果在1列2個重複條目,我想在柱與下值除去行2

或者,如果有在1列2名以上相同的條目然後我想第2行的中間值保持不變。因此,對於數據幀

a <- c(rep("A", 3), rep("B", 3), rep("C",1), rep("D",1), rep("D",1)) 
b <- c(1,2,3,4,5,6,4,7,6) 
df <-data.frame(a,b) 

將成爲

a <- c(rep("A", 1), rep("B", 1), rep("C",1), rep("D",1)) 
b <- c(2,5,4,7) 
df <-data.frame(a,b) 

我已經試過功能獨特的()和重複(),但似乎無法找到符合這些標準的爭論。任何幫助非常感謝。

+0

對於基數R,您還可以查看'?aggregate'。 – SimonG

回答

3

使用dplyr

library(dplyr) 

df %>% group_by(a) %>% 
    summarise(b = ifelse(n() == 2, min(b), median(b))) 

    a b 
1 A 2 
2 B 5 
3 C 4 
4 D 6 

在你的問題,你說你想要的 「低」 的值,如果有兩行,這將使d = 6,而不是d = 7。如果您的意思是數據框中出現的第一行,您可以這樣做:

df %>% group_by(a) %>% 
    summarise(b = ifelse(n() == 2, b[1], median(b))) 
+0

非常好 - 非常感謝。所有工作完美! – MLyall

4

您可以嘗試

library(data.table) 
setDT(df)[, list(b=if(.N==2) min(b) else median(b)) , by = a] 
# a b 
#1: A 2 
#2: B 5 
#3: C 4 
#4: D 6 

或用aggregate

aggregate(b~a, df, FUN=function(x) if(length(x)==2) min(x) else median(x)) 
# a b 
#1 A 2 
#2 B 5 
#3 C 4 
#4 D 6 

或者

library(sqldf) 
sqldf('select a, 
     case 
      when count(b) is 2 then min(b) 
      else median(b) 
     end b 
     from df 
     group by a') 
# a b 
#1 A 2 
#2 B 5 
#3 C 4 
#4 D 6 

的類似選項基於預期的輸出結果顯示,最後一行是D 7,所以如果當組長度爲2時,我們選擇第一個觀察值,

setDT(df)[, list(b=if(.N==2) b[1L] else median(b)) , by = a] 
# a b 
#1: A 2 
#2: B 5 
#3: C 4 
#4: D 7 

或者

aggregate(b~a, df, FUN=function(x) if(length(x)==2) x[1L] else median(x)) 
# a b 
#1 A 2 
#2 B 5 
#3 C 4 
#4 D 7 

或者

sqldf('select a, 
      case 
      when count(b) is 2 and min(rowid) then b 
      else median(b) 
      end b 
     from df 
     group by a') 
# a b 
#1 A 2 
#2 B 5 
#3 C 4 
#4 D 7 

編輯改變第一觀察min後,我看到了@ eipi10的帖子。沒有正確閱讀OP的帖子,OP的預期輸出與描述不符。