2016-04-24 54 views
3

我有以下問題:在數據框中,我有很多行和列,第一行是日期。對於每個日期我有超過1個觀察,我想總結它們。概述具有不同功能的不同列

我DF看起來像(日期取代ID爲易用性):

df: 
ID  Cash Price Weight ... 
1  0.4  0  0 
1  0.2  0  82  ... 
1  0  1  0  ... 
1  0  3.2  80  ... 
2  0.3  1  70  ... 
... ...  ...  ...  ... 

我想第一列組他們,然後總結所有行,但具有不同的功能:

功能現金和價格應該是總和所以我得到每個ID的現金和價格的總和。 Weight上的功能應該是max,所以我只能得到ID的最大權重。

因爲我有這麼多列,我不能手工寫的所有功能,但我只有2列應由最大其餘應由總和歸納總結。

所以我要尋找的ID的功能組,彙總所有與總和除了我需要最大值2個不同的列。

我試圖與使用dplyr包:

df %>% group_by(ID = tolower(ID)) %>% summarise_each(funs(sum)) 

但我需要的除了不總結,但最多2個指定的列,任何想法?

要清楚的例子DF的輸出應該是:

ID  Cash  Price Weight 
1  0.6  4.2  82  
2  0.3  1   70 
做的

回答

2

我們可以使用

df %>% 
    group_by(ID) %>% 
    summarise(Cash = sum(Cash), Price = sum(Price), Weight = max(Weight)) 

如果我們有很多列,一種方法是將d這個分開然後join一起輸出。

df1 <- df %>% 
      group_by(ID) %>% 
      summarise_each(funs(sum), Cash:Price) 
df2 <- df %>% 
      group_by(ID) %>% 
      summarise_each(funs(max), Weight) 
inner_join(df1, df2, by = "ID") 
#  ID Cash Price Weight 
# (int) (dbl) (dbl) (int) 
#1  1 0.6 4.2  82 
#2  2 0.3 1.0  70 
2
library(data.table) 

setDT(df) 

df[,.(Cash = sum(Cash),Price = sum(Price),Weight = max(Weight)),by=ID] 

其中一種方法爲+90列可以是:

max_col <- 'Weight' 

sum_col <- setdiff(colnames(df),max_col) 

query_1 <- paste0(sum_col,' = sum(',sum_col,')') 

query_2 <- paste0(max_col,' = max(',max_col,')') 

query_3 <- paste(query_1,collapse=',') 

query_4 <- paste(query_2,collapse=',') 

query_5 <- paste(query_3,query_4,sep=',') 

final_query <- paste0('df[,.(',query_5,'),by = ID]') 

eval(parse(text = final_query)) 
+1

謝謝,這似乎工作!除了「重量」之外,是否還有一項補充將** sum **應用於所有列,並且僅將** max **用於「重量」欄和另一個欄?因爲我有90多列,這將是一個痛苦寫:) – Max

+0

@Max這是你可以使用'data.table'完成任務的方式之一 –

3

或者做W/O型的雙組:

library(dplyr) 

set.seed(1492) 
df <- data.frame(id=rep(c(1,2), 3), 
       cash=rnorm(6, 0.5, 0.1), 
       price=rnorm(6, 0.5, 0.1)*6, 
       weight=sample(100, 6)) 

df 

## id  cash price weight 
## 1 1 0.4410152 2.484082  10 
## 2 2 0.4101343 3.032529  93 
## 3 1 0.3375889 2.305076  58 
## 4 2 0.6047922 3.248851  55 
## 5 1 0.4721711 3.209930  34 
## 6 2 0.5362493 2.331530  99 

custom_summarise <- function(do_df) { 

    return(bind_cols(
    summarise_each(select(do_df, -weight), funs(sum)), 
    summarise_each(select(do_df, weight), funs(max)) 
)) 

} 

group_by(df, id) %>% do(custom_summarise(.)) 

## Source: local data frame [2 x 4] 
## Groups: id [2] 
## 
##  id  cash price weight 
## (dbl) (dbl) (dbl) (int) 
## 1  3 1.250775 7.999089  58 
## 2  6 1.551176 8.612910  99