2017-01-03 20 views
3

各行が1イベントを表す列グループ、勘定および期間を含むチブルがあります。グループ、勘定、合計期間、計算された価格、最終的には合計期間のグループ比率を含むすばらしいサマリテーブルを作成したいと思います。dplyrを使用して複数の変数でグループ化する場合の変数の割合の計算

再現サンプル:

library(tidyverse) 
library(lubridate) 
tidy_data <- structure(list(group = c("Group 1", "Group 2", "Group 3", "Group 1", "Group 2", "Group 3", "Group 4", "Group 4", "Group 2"), account = c("Account 1", "Account 2","Account 3", "Account 1", "Account 2", "Account 3", "Account 4", "Account 4", "Account 2"), duration = structure(c(146.15, 181.416666666667, 96.9, 52.2833333333333, 99.4333333333333, 334.116666666667, 16.6333333333333, 11.5666666666667, 79.5666666666667), units = "mins", class = "difftime")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -9L), .Names = c("group","account", "duration")) 
hourPrice = 25 

が概要1 - 正しく割合を計算しますが、口座番号

tidy_data %>% 
    group_by(group) %>% 
    summarise(total = sum(duration) %>% time_length(unit = "hour") %>% round(digits = 2), 
         price = (total*hourPrice) %>% round(digits = 0)) %>% 
    mutate(prop = (price/sum(price) * 100) %>% round(digits = 0)) 

# A tibble: 4 × 4 
    group total price prop 
    <chr> <dbl> <dbl> <dbl> 
1 Group 1 3.31 83 20 
2 Group 2 6.01 150 35 
3 Group 3 7.18 180 42 
4 Group 4 0.47 12  3 

概要2含まれていません - 口座番号が含まれていますが、正しく

割合を計算するために失敗します
tidy_data %>% 
    group_by(group, account) %>% 
    summarise(total = sum(duration) %>% time_length(unit = "hour") %>% round(digits = 2), 
         price = (total*hourPrice) %>% round(digits = 0)) %>% 
    mutate(prop = (price/sum(price) * 100) %>% round(digits = 0)) 

#Source: local data frame [4 x 5] 
#Groups: group [4] 

    group account total price prop 
    <chr>  <chr> <dbl> <dbl> <dbl> 
1 Group 1 Account 1 3.31 83 100 
2 Group 2 Account 2 6.01 150 100 
3 Group 3 Account 3 7.18 180 100 
4 Group 4 Account 4 0.47 12 100 

私はこの問題は、2つの2つ目のケースでは、1つのグループ内の作品のみを集計します。私は要約1を実行し、アカウント番号をテーブルに戻すことを検討しましたが、より良い解決策が必要であると私には思われます。

EDIT:出力は、私が希望:

group account total price prop 
    <chr>  <chr> <dbl> <dbl> <dbl> 
1 Group 1 Account 1 3.31 83 20 
2 Group 2 Account 2 6.01 150 35 
3 Group 3 Account 3 7.18 180 42 
4 Group 4 Account 4 0.47 12  3 

答えて

0

代わりのsummarise、我々はデータセット内の新しい列を作成するためにmutateを使用し、各「グループ」のslice最初の行は、「小道具を計算します'期間を削除してください。

tidy_data %>% 
     group_by(group) %>% 
     mutate(total = sum(duration) %>% 
       time_length(unit = "hour") %>% 
       round(digits = 2), 
       price = (total*hourPrice) %>% 
       round(digits = 0)) %>% 
     slice(1L) %>% 
     ungroup() %>% 
     mutate(prop = (price/sum(price) * 100) %>% 
      round(digits = 0)) %>% 
     select(-duration)  
# A tibble: 4 × 5 
#  group account total price prop 
#  <chr>  <chr> <dbl> <dbl> <dbl> 
# 1 Group 1 Account 1 3.31 83 20 
# 2 Group 2 Account 2 6.01 150 35 
# 3 Group 3 Account 3 7.18 180 42 
# 4 Group 4 Account 4 0.47 12  3 
+1

それはトリックです! :-)私はスライスコマンドを知らなかったし、最初は各グループの最初の行を選ぶだろうと私に直感的ではなかったが、私はこの解決策が好きだ。 – emiltb

関連する問題