2016-10-25 7 views
1

3つの異なるメソッド(method1、method2、method0)を持つ2つのサイト(A & B)、2つのグループ(グループ1 & 2)からの推定値を含むデータフレームdfがあります。コントロールまたはベースライングループを持つデータフレームのR計算

df1<-data.frame(site=rep("A", 21), 
       group=rep("group1", 21), 
       estimate=c(rnorm(10, 15, 3), rnorm(10, 2, 7), rnorm(1, 6, 2)), 
       method=c(rep(c("method1","method2"),each=10),"method0")) 

df2<-data.frame(site=rep("B", 21), 
       group=rep("group2", 21), 
       estimate=c(rnorm(10, 13, 3), rnorm(10, 5, 7), rnorm(1, 9, 2)), 
       method=c(rep(c("method1","method2"),each=10),"method0")) 
df<-rbind(df1, df2) 
df 
    site group estimate method 
1  A group1 15.1561073 method1 
2  A group1 14.4067422 method1 
3  A group1 12.7428921 method1 
.......... 

41 B group2 0.3548033 method2 
42 B group2 10.5820482 method0 

Iは、ベースライングループとしてmethod0を使用し、各サイト/グループの各推定値に対する相対パーセンテージバイアス(RB)を算出したいです。

#for each site and group of estimate 
rb<-(estimate-estimate0)/estimate0*100% 

# where estimate0 is the estimate of method0 of that certain site/group 

各サイト/グループには1つしかありません。私はシンプルな関数を書こうとしていて、各サイト/グループに対してapplyを使用しましたが、うまくいきませんでした。

fun.rb<-function(df, basline){ 
    control<-df$method==baseline 
    rb<-(df$estimate-control$estimate)/(control$estimate)*100% 
    return(rb) 
}  
df %>% group_by(site,group) %>% mutate(rb=fun.rb, baseline="method0") 

すべての入力とコメントは非常に高く評価されています。

答えて

1

ここでは、あなたがやろうとしているもののシンプルで洗練された方法があります。

まず、(your'eはパイプでそれを使用するつもりならば、それは引数として全体DFを取る必要はありません)あなたの機能を簡素化:

fun.rb <- function(estimate, baseline){ 
    (estimate-baseline)/(baseline)*100 
}  

を今、すべてのあなたが必要行うには、ベースラインの列を作成し、各行の関数を呼び出して、推定値とベースラインの列を関数に渡します。

df <- df %>% 
    group_by(site,group) %>% 
    mutate(baseline = estimate[method=="method0"], rb = fun.rb(estimate, baseline)) 
+0

うわー、それは素晴らしいですね。私の機能を固定してくれてありがとう。 – lamushidi

+0

私はあなたが実際に関数を必要としないことを指摘し、関数内の計算で関数呼び出しを置き換えることで、インラインで全体を行うことができます。 – yeedle

+0

はい、もちろんです。そうすれば、コードをもっときれいにすることができます。どうもありがとう。 – lamushidi

1

これは最もエレガントではないかもしれません。私はちょうどハックだ。しかし、私はそれがあなたが望むことをすると思います。

> library(dplyr) 
> newdf <- df %>% filter(method=="method0") %>% 
+ rename(method0_value = estimate) %>% 
+ select(-method) 
> head(newdf) 
    site group method0_value 
1 A group1  2.529237 
2 B group2  7.863411 

このデータセットには、すべてのベースライン/コントロール値が含まれます。 コードの次のビットは、それを最初のデータフレームにマージし、必要な変数を作成します。必要に応じてmethod0_valueを削除することができます。それは素晴らしいチェックです。

> finaldf <- left_join(df,newdf,by=c("site","group")) %>% 
+ mutate(rb= (estimate/method0_value)*100) 
> head(finaldf) 
    site group estimate method method0_value  rb 
1 A group1 8.928171 method1  2.529237 352.9986 
2 A group1 11.171023 method1  2.529237 441.6757 
3 A group1 10.790150 method1  2.529237 426.6169 
4 A group1 8.990635 method1  2.529237 355.4683 
5 A group1 14.813661 method1  2.529237 585.6969 
6 A group1 14.518803 method1  2.529237 574.0390 

もっと効率的かもしれないこの方法を知っていますが、私はまだnoobです。

+0

ありがとうございます。これはかなり直感的ですが、実際には2行のコードしか必要としません。それに素晴らしい機能を書く必要はありません。 – lamushidi

関連する問題