2016-10-04 4 views
0

カテゴリ変数を含むデータセットがあります。この変数の値に応じて、そのような値ごとに異なる関数を実行したいと思います。すべての可能な関数は同じ戻り型を持ちます。カテゴリが 'A'の場合はsin()、カテゴリが 'B'の場合はcos()、カテゴリが 'C'の場合はtan()を実行するとよいでしょう。dplyrで別の変数の値に応じて各項目に対して別の関数を実行

実際のアプリケーションは、結果がカテゴリの値に依存する集団をシミュレートすることですが、時には非常に異なる方法で行われます。

玩具例

library(dplyr) 
category=c('A','B','C') 
N <- 100 
pop <- as.data.frame(ID <- seq(1:N)) 
pop <- as.tbl(pop) 
pop$Category <- sample(category,N,replace=TRUE) 
pop$score <- runif(N) 
pop 
tf <- function(x,EXPR) { 
switch(EXPR, 
A = cos(x), 
B = sin(x), 
C = tan(x) 
)} 
pop$results <- tf(pop$Score,pop$Category) 

このコードは失敗し、合理的に十分な、エラーメッセージ

Error in switch(EXPR, A = cos(x), B = sin(x), C = tan(x)) : EXPR must be a length 1 vector 

と私はdplyrで、慎重に、見てください、と私は簡単にどのように見ることができています各カテゴリごとに同じ機能を別々に実行します。しかし、私はカテゴリの値に依存する関数が必要です。

大変感謝しています。

+4

は例が再現させるためのコードを編集してください動作します。 – ulfelder

+0

私はその動きの秒です。 'ポップ'とは何ですか? – aichao

+0

申し訳ありませんが、よく目に付きます - ポップは単なるデータフレームであり、テストを実行したときに自分の環境に存在していたはずです。 – astaines

答えて

2

rowwise機能を使用して、行ごとに評価し、それを強制するために必要なものである...

pop<-data.frame(ID=1:100, 
        category = sample(c("A", "B", "C"),100,replace=TRUE), 
        score = runif(100)) 

    exprs<-function(category, score){ 
     if(category=="A") 
      ret <- sin(score) 
     if(category=="B") 
      ret <- cos(score) 
     if(category=="C") 
      ret <- tan(score) 
     ret } 



    pop %>%  
     rowwise %>%  
     mutate(answer = exprs(category, score)) 

出典:ローカル・データ・フレーム[100×4] グループ:

# A tibble: 100 × 4 
     ID category  score answer 
    <int> <fctr>  <dbl>  <dbl> 
1  1  C 0.5219332 0.5751317 
2  2  C 0.9266336 1.3314972 
3  3  B 0.2729260 0.9629863 
4  4  B 0.6575110 0.7915158 
5  5  B 0.0910481 0.9958580 
6  6  C 0.9968752 1.5467554 
7  7  A 0.3429183 0.3362369 
8  8  A 0.9101669 0.7896062 
9  9  B 0.9291849 0.5984872 
10 10  C 0.8913347 1.2379742 
# ... with 90 more rows 
+0

ああ、そういうのは行ごとのことです - 良いアドバイス、もっと学ぶチャンスです。どうもありがとうございました。 – astaines

1

あなたはすることができます使用するVectorize()

category=c('A','B','C') 
N <- 10 
pop <- data.frame(ID=seq(1:N), Category=sample(category,N,replace=TRUE), score=runif(N), stringsAsFactors = FALSE) 

tf <- function(x, EXPR) switch(EXPR, 
     'A' = cos(x), 
     'B' = sin(x), 
     'C' = tan(x)) 

TF <- Vectorize(tf) 

pop$result <- TF(pop$score, pop$Category) 
+0

非常に興味深いです、私は前にその機能を見ていませんでした。どうもありがとうございました。 – astaines

1

このエラーは、レコードワイズではなく、完全なベクトルを送信していますか?私は、行ごとに、あなたの関数を呼び出すためにlapply使用し、それはあなたのおもちゃの例のコードは、4行目で失敗

library(dplyr) 
category=c('A','B','C') 
N <- 100 
pop <- data.frame(ID = seq(1:N)) 
pop$Category <- sample(category,N,replace=TRUE) 
pop$Category <- as.factor(pop$Category) 
pop$score <- runif(N) 
tf <- function(x,EXPR) { 
    switch(EXPR, 
     A = cos(x), 
     B = sin(x), 
     C = tan(x) 
)} 

## call tf for every row in the dataframe 
pop$results <-lapply(seq_len(nrow(pop)) , function (i) {  
    tf(pop$score[i],pop$Category[i]) 
}) %>% unlist 

おかげ

+0

私はいつもラッピー、サプリなどを覚えて苦労しています。良いアドバイス、ありがとう。 – astaines

関連する問題