2016-12-10 25 views
1

私はこのサイトで多くの条件付き突然変異質問をしましたが、私の問題はそれらよりも複雑です。ここに私のデータ構造です:複雑な条件付き突然変異

d = matrix(data = NA, ncol = 3, nrow = 9) 
d = as.data.frame(d) 
colnames(d) = c('group', 'type', 'v1') 
d$group = c(1,1,1,2,2,2,2,2,2) 
d$type = c(1,2,3,1,2,3,3,3,3) 
d$v1 = c(43,21,234,5,56,6,56,4,345) 


group type v1 
1 1 43 
1 2 21 
1 3 234 
2 1 5 
2 2 56 
2 3 6 
2 3 56 
2 3 4 
2 3 345 

この2グループ化変数があります:grouptypeを。ように私は、新しい変数v2を作成する必要があります。各グループの

  • 、もしtype == 1v2 = 1

  • 各グループには、type == 2場合、v2 = [v1(type2) - v1(type1)]/[v1(type2) + v1(type1)]。例えば、グループ1にtype == 2、各群におけるv2 = (21-43)/(21 + 43)

  • type == 3場合、同じ機能v2 = [v1(type3) - v1(type1)]/[v1(type3) + v1(type1)]を適用します。例えば、グループ1、type == 3で、v2 = (234 - 43)/(234 + 43)

私のデータセットは、200個の以上のグループがあります。各グループでは、タイプ3の頻度も異なります。ここで

は私がやったことだ: 私は式の機能作成:

flsm = function(x, y){(x - y)/(x + y)} 

をそして、私はv2を計算してみてください。

d %>% group_by(group) %>% 
    mutate(v2 = ifelse(type == 2, 
         flsm(v1, type == 1[v1])), 
         ifelse(type == 3, flsm(v1, type == 1[v1])), 1) 

これは、次の警告が返されました:

Error: argument "no" is missing, with no default 
In addition: Warning messages: 
1: In is.na(e1) | is.na(e2) : 
    longer object length is not a multiple of shorter object length 
2: In `==.default`(c(1L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), 1[c(6.27, :longer object length is not a multiple of shorter object length 

私は正しいアプローチからやっていないような気がします。 。 v2の計算方法は?

+0

'flsm'を呼び出すたびに余分な括弧があるようです。 ifelse(type == 3、flsm(v1、type == 1 [v1])、1(v1、type == 1 [v1])、 ifelse ) '。私はそれが唯一の問題かどうかは分かりませんが、あなたのコードが修正されているかどうかを確認してください。 – eipi10

答えて

2

あなたはv1によって1のインデックスを作成、いくつかの奇妙なサブセット化をしようとしています。代わりにあなたの説明を行く、あなたが行うことができます列全体を参照し、グループ内や.$column_name変数を参照するために裸の列名を使用することができます。ここでは

d %>% group_by(group) %>% 
    mutate(v2 = ifelse(type == 1, 1, 
         flsm(v1, .$v1[.$group == unique(group) & .$type == 1]))) 

## Source: local data frame [9 x 4] 
## Groups: group [2] 
## 
## group type v1   v2 
## <int> <int> <int>  <dbl> 
## 1  1  1 43 1.00000000 
## 2  1  2 21 -0.34375000 
## 3  1  3 234 0.68953069 
## 4  2  1  5 1.00000000 
## 5  2  2 56 0.83606557 
## 6  2  3  6 0.09090909 
## 7  2  3 56 0.83606557 
## 8  2  3  4 -0.11111111 
## 9  2  3 345 0.97142857 
+0

ありがとう!それはかなりうまくいく! – Marble

1

ベースRでこれを行う方法は次のとおりです。同じことをするためにパッケージを使用したい場合はここから簡単です。

df1$v2 <- NA 

for(i in df1$gr){ 
    #in each group, if tye==1, v2=1 
    df1$v2[df1$tye==1 & df1$gr==i] <- 1 

    #in each group, if tye==2, v2=[v1(tye2)-v1(tye1)]/[v1(tye2)+v1(tye1)]. 
    df1$v2[df1$tye==2 & df1$gr==i] <- (df1$v1[df1$tye==2 & df1$gr==i] - df1$v1[df1$tye==1 & df1$gr==i])/(df1$v1[df1$tye==2 & df1$gr==i] 
                    +df1$v1[df1$tye==1 & df1$gr==i]) 



    #in each group, if tye==3, apply the same function v2=[v1(tye3)-v1(tye1)]/[v1(tye3)+v1(tye1)]. 
    df1$v2[df1$tye==3 & df1$gr==i] <- (df1$v1[df1$tye==3 & df1$gr==i] - df1$v1[df1$tye==1 & df1$gr==i])/(df1$v1[df1$tye==3 & df1$gr==i] 
              +df1$v1[df1$tye==1 & df1$gr==i]) 
} 
gr tye v1   v2 
1 1 1 43 1.00000000 
2 1 2 21 -0.34375000 
3 1 3 234 0.68953069 
4 2 1 5 1.00000000 
5 2 2 56 0.83606557 
6 2 3 6 0.09090909 
7 2 3 56 0.83606557 
8 2 3 4 -0.11111111 
9 2 3 345 0.97142857 
+0

ありがとうございました!コードを適用したところ、次の警告が返されました:d $ v2 [d $ tye == 3&d $ gr == i] < - (d $ v2 [d $ tye ==: 置換は長さゼロです。 – Marble

+0

@Marble元のデータを実行すると、上記の結果が生成されます。私はあなたの編集後に列名が変更されたため、エラーがあると推測します。 –

+0

最初の100行が正常に動作したが、その後は次の行がNAだったのは変だ。 – Marble

0

が割り当てdata.tableとオプションですin place

library(data.table) 
setDT(d)[, v2:= flsm(v1, d$v1[d$group==unique(group) & d$type ==1]) , group 
        ][type==1, v2 := 1][] 
# group type v1   v2 
#1:  1 1 43 1.00000000 
#2:  1 2 21 -0.34375000 
#3:  1 3 234 0.68953069 
#4:  2 1 5 1.00000000 
#5:  2 2 56 0.83606557 
#6:  2 3 6 0.09090909 
#7:  2 3 56 0.83606557 
#8:  2 3 4 -0.11111111 
#9:  2 3 345 0.97142857 
関連する問題