2016-04-24 5 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  ... 
... ...  ...  ...  ... 

私は最初の列でグループにしたいし、すべての行をまとめるが、異なる機能を持つ:

関数CashとPriceはの合計である必要がありますので、各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)) 

多くの列がある場合は、1つの方法で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列のためにこれを行う方法の1つは、することができ:

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

おかげで、これは動作しているようです! '加重'を除いたすべての列に**合計**を適用する追加がありますか? '重さ'の列には**最大**を使用します。私は90+の列を持っているので、これは書くのに苦労するでしょう:) – Max

+0

@Maxそれはあなたが 'data.table'を使ってタスクを達成する方法の一つです –

3

は、二重のグループO/Wそれを実行します。

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