2017-07-30 6 views
6

私は以下のデータフレームを持っています。私は異なるUSAGEで同じTYPEを持つすべてのIDを見つけることを意図しています。私はmultidplyrとgroup_by()とfilter()

df %>% group_by(ID, TYPE) %>% filter(n_distinct(USAGE)>1) 

を実行する場合

ID <- rep(1:4, each=3) 
USAGE <- c("private","private","private","private", 
"taxi","private","taxi","taxi","taxi","taxi","private","taxi") 
TYPE <- c("VW","VW","VW","VW","MER","VW","VW","VW","VW","VW","VW","VW") 
df <- data.frame(ID,USAGE,TYPE) 

私が意図した結果を取得します。しかし、私の元のデータフレームは2百万行以上あります。だから私はこの操作を実行する際にすべてのコアを使いたいと思っています。

f1 <- partition(df, ID) 
f2 <- f1 %>% group_by(ID, TYPE) %>% filter(n_distinct(USAGE)>1) 
f3 <- collect(f2) 

しかし、その後、次のメッセージが表示されます:

Warning message: group_indices_.grouped_df ignores extra arguments 

f1 <- partition(df, ID) 

Error in checkForRemoteErrors(lapply(cl, recvResult)) : 
    4 nodes produced errors; first error: Evaluation error: object 'f1' not found. 

私はmultidplyrでこのコードを試してみましたmultidplyrに全体の動作を実現するための正しい方法だろう何

f2 <- f1%>% group_by(ID, TYPE) %>% filter(f1, n_distinct(USAGE)>1) 

?どうもありがとう。

答えて

2

partition()への呼び出しにすべてのグループ化変数を含める必要があります。こうすることで、各コアには、特定のグループの計算を実行するために必要なすべてのデータが保持されます。

library(tidyverse) 
library(multidplyr) 

fast <- df %>% 
    partition(ID, TYPE) %>% 
    group_by(ID, TYPE) %>% 
    filter(n_distinct(USAGE) > 1) %>% 
    collect() 

検証

あなたはまだgroup_indicesについての警告を取得しますが、結果は、元dplyr方法と同じです。

slow <- df %>% 
    group_by(ID, TYPE) %>% 
    filter(n_distinct(USAGE) > 1) 

fast == slow 
     ID USAGE TYPE 
#[1,] TRUE TRUE TRUE 
#[2,] TRUE TRUE TRUE 
#[3,] TRUE TRUE TRUE 

ベンチマーク今

大きな問題:それは速いのですか? clusterを定義することで、すべてのコアを確実に使用できるようになります。並列処理を使用

library(microbenchmark) 
library(parallel) 

cluster <- create_cluster(cores = detectCores()) 

fast_func <- function(df) { 
    df %>% 
    partition(ID, TYPE, cluster = cluster) %>% 
    group_by(ID, TYPE) %>% 
    filter(n_distinct(USAGE) > 1) %>% 
    collect() 
} 

slow_func <- function(df) { 
    slow <- df %>% 
    group_by(ID, TYPE) %>% 
    filter(n_distinct(USAGE) > 1) 
} 

microbenchmark(fast_func(df), slow_func(df)) 
# Unit: milliseconds 
# expr  min  lq  mean median  uq  max neval cld 
# fast_func(df) 41.360358 47.529695 55.806609 50.529851 61.459433 133.53045 100 b 
# slow_func(df) 4.717761 6.974897 9.333049 7.796686 8.468594 49.51916 100 a 

は、実際に、この場合の遅いです。 fast_funcの実行の中央値は、9ではなく56ミリ秒かかります。これは、クラスタ間のデータフローの管理に伴うオーバーヘッドが原因です。しかし、あなたのデータには何百万もの行があると言いましたので、それを試してみましょう。巨大なデータセットで

# Embiggen the data 
df <- df[rep(seq_len(nrow(df)), each=2000000),] %>% tbl_df() 

microbenchmark(fast_func(df), slow_func(df)) 
# Unit: seconds 
# expr  min  lq  mean median  uq  max neval cld 
# fast_func(df) 43.067089 43.781144 50.754600 49.440864 55.308355 65.499095 10 b 
# slow_func(df) 1.741674 2.550008 3.529607 3.246665 3.983452 7.214484 10 a 

fast_funcはまだ遅いです!並行して実行すると膨大な時間が節約されることもありますが、単純なグループ化されたフィルタは必ずしもその1つではありません。

関連する問題