2016-03-23 2 views
2

私はデータセットを持っており、グループ化ロールアップのようなものを実行したいと思います。Rでロールアップする方法(SQLのような)

以下は再現可能な例です。私は集約が実際によく説明されているとわかりますhereしかし、私の場合には満足できるものではありません。

year<- c('2016','2016','2016','2016','2017','2017','2017','2017') 
month<- c('1','1','1','1','2','2','2','2') 
region<- c('east','west','east','west','east','west','east','west') 
sales<- c(100,200,300,400,200,400,600,800) 
df<- data.frame(year,month,region,sales) 
df 


year month region sales 
1 2016  1 east 100 
2 2016  1 west 200 
3 2016  1 east 300 
4 2016  1 west 400 
5 2017  2 east 200 
6 2017  2 west 400 
7 2017  2 east 600 
8 2017  2 west 800 

は今、私が何をしたいか集約(年 - 月 - 地域別sum-)と、既存のデータフレーム 例えば、新しい集計行を追加することですそこに私は(下記)の方法を考え出した

year month region sales 
1 2016  1 east 400 
2 2016  1 west 600 
3 2016  1 USA 1000 
4 2017  2 east 800 
5 2017  2 west 1200 
6 2017  2 USA 2000 

aggreagted行は「USA」などの地域のための新しい名前で以下のような二つの追加列ことが、私はのための最適なソリューションが存在することを非常に確信している必要がありますこのより良い回避策は私よりも

df1<- setNames(aggregate(df$sales, by=list(df$year,df$month, df$region), FUN=sum), 
    c('year','month','region', 'sales')) 


df2<- setNames(aggregate(df$sales, by=list(df$year,df$month), FUN=sum), 
       c('year','month', 'sales')) 

df2$region<- 'USA'     ## added a new column- region- for total USA 
df2<- df2[, c('year','month','region', 'sales')] ## reordering the columns of df2 

df3<- rbind(df1,df2) 

df3<- df3[order(df3$year,df3$month,df3$region),] ## order by 
rownames(df3)<- NULL ## renumbered the rows after order by 

df3 

ありがとうございます! reshape2パッケージの

答えて

3

melt/dcast subtotallingを行うことができます。

library(reshape2) 
library(zoo) 

m <- melt(df, measure.vars = "sales") 
dout <- dcast(m, year + month + region ~ variable, fun.aggregate = sum, margins = "month") 

dout$month <- na.locf(replace(dout$month, dout$month == "(all)", NA)) 

寄付:

> dout 
    year month region sales 
1 2016  1 east 400 
2 2016  1 west 600 
3 2016  1 (all) 1000 
4 2017  2 east 800 
5 2017  2 west 1200 
6 2017  2 (all) 2000 
+0

あなたの答えは非常に近いですが、3行目と6行目に月も入力してください。回避策はありますか? – freetiger

+0

にはna.locfが追加され、小計の行に月を記入し、後で修正することなくdcastに正しい名前を生成させるメルトを追加しました。また、望ましくないと思われる総計を削除しました。 –

+0

ダング!あなたの言葉を雑誌で見ただけです。あなたは動物園や他のクラスの作成者です。 :) – freetiger

-1
plyr::ddply(df, c("year", "month", "region"), plyr::summarise, sales = sum(sales)) 
+1

これは、私の例(集約を使用)では、希望の答えではなく、df1のo/pです。 – freetiger

1

最近のdevel data.table 1.10.5で使用できる新機能dcastを実行した後、私たちは動物園のパッケージからna.locfを使用して、月と月のコラムで"(all)"を置き換えます

library(data.table) 
setDT(df) 
res = groupingsets(df, .(sales=sum(sales)), sets=list(c("year","month"), c("year","month","region")), by=c("year","month","region")) 
setorder(res, na.last=TRUE) 
res 
# year month region sales 
#1: 2016  1 east 400 
#2: 2016  1 west 600 
#3: 2016  1  NA 1000 
#4: 2017  2 east 800 
#5: 2017  2 west 1200 
#6: 2017  2  NA 2000 

あなたはへNAを置き換えることができます:サブ合計を生成する「のセットをグループ化」と呼ばれます3210はres[is.na(region), region := "USA"]を使用しています。

関連する問題