2017-11-16 30 views
1

この辺りで私の頭を掴みようとしています。dplyr。変数に基づいてグループ化したいソートされたデータフレームがあります。しかし、グループは、それぞれがグループ化変数上で最小合計30を持つように構成する必要があります。dplyrを動的group_byに使用する

は、この小さな例のデータフレームを考えてみましょう:

df1 <- matrix(data = c(05,0.9,95,12,0.8,31, 
    16,0.8,28,17,0.7,10, 
     23,0.8,11,55,0.6,9, 
    56,0.5,12,57,0.2,1, 
    59,0.4,1), 
    ncol = 3, 
    byrow = TRUE, 
    dimnames = list(c(1:9), 
    c('freq', 'mean', 'count') 
) 
) 

countは、少なくとも30 freqmeanの合計が、その後重みがあるweighted.meanに崩壊する必要があります持っているように、私はグループにしたいですcount値。最後の "bin"は行7で32の合計に達しますが、行8:9は2にしか足らないので、最後の "bin"に加算します。

ので、同じように:

freq mean count 
5.00 0.90 95 
12.00 0.80 31 
16.26 0.77 38 
45.18 0.61 34 

dplyrとの簡単な要約は問題ではありませんが、これは私が把握することはできません。私は解決策はどこかにここに隠されていると思います:

Dynamic Grouping in R | Grouping based on condition on applied function

しかし、どのように私の状況に適用するには私をエスケープします。

答えて

2

私はもっと短期間の解決策を望んでいましたが、ここで私が思いついたのはここです。

まず、我々はカスタムCUMSUM関数を定義します。

library(dplyr) 
library(tidyr) 

df1 %>% 
    as.data.frame %>%      # as you started with a matrix 
    mutate(id = row_number(),    # we'll need this to sort in the end 
     cumcount = cumsum2(count)) %>% # adding nex cumulate count 
    `[<-`(.$cumcount < 30,"cumcount",NA) %>% # setting as NA values less than 30 ... 
    fill(cumcount,.direction = "up")  %>% # ... in order to fill them with cumcount 
    fill(cumcount,.direction = "down") %>% # the last NAs belong to the last group so we fill down too 
    group_by(cumcount)     %>% # these are our new groups to aggregate freq and mean 
    summarize(id = min(id), 
      freq = sum(freq*count)/sum(count), 
      mean = sum(mean*count)/sum(count)) %>% 
    arrange(id)       %>% # sort 
    select(freq,mean,count=cumcount)   # and lay out as expected output 

# # A tibble: 4 x 3 
#  freq  mean count 
#  <dbl>  <dbl> <dbl> 
# 1 5.00000 0.9000000 95 
# 2 12.00000 0.8000000 31 
# 3 16.26316 0.7736842 38 
# 4 45.17647 0.6117647 32 

cumsum2 <- function(x){ 
    Reduce(function(.x,.y){ 
    if(tail(.x,1)>30) x1 <- 0 else x1 <- tail(.x,1) ;c(.x,x1+.y)},x,0)[-1] 
} 
# cumsum2(1:10) 
# [1] 1 3 6 10 15 21 28 36 9 19 

その後、我々はdplyrチェーンを楽しんでいることができます

関連する問題