2014-02-15 23 views
1

我有一個大的數據集是這樣的:R:應用功能,通過要素數據幀的每一行,在函數調用的值(由因子)

my.df <- data.frame(Cond= rep(c("A", "B", "C", "D"), each = 4), 
      Gene = rep(c("Gene1", "Gene2", "Gene3", "Gene4"), 4), 
      Avg=sample(85:100, 16, replace = TRUE), 
      SE=sample(1:5, 16, replace = TRUE), 
      Val1=sample(1:50, 16), 
      Val2=sample(1:50, 16)) 

現在,對於每個基因,我想正常化的一切(除「平均」的每個值,「SE」,「VAL1」和「VAL2」通過)爲電導率A的平均價值

我現在的想法是做這樣的事情:

by(my.df[ , 3:6], Gene, #since I want to do my calculation on each Gene 
    lapply(function(x) #since I want to do my calculation on each value 

但我不知道如何編寫函數,以便它需要當前值爲x,並將其除以該基因的Cond A Avg值。

或者,它發生在我,使含有基因和電導率一個平均數值的另一個數據幀:

CondAavg <- my.df[Cond =="A", c("Gene","Avg")] 

,然後嘗試使用sapply的功能適用於「基因」的每個值,但我也不太清楚如何做這項工作。

我對R顯然還是很新的,所以任何建議都會非常感謝。

回答

0

我會做2個步驟,使用merge

dtm = merge(subset(my.df,Cond!='A'), 
    subset(my.df,Cond=='A',select=c('Gene','Avg')),by='Gene') 
    Gene Cond Avg.x SE Val1 Val2 Avg.y 
1 Gene1 B 97 4 9 29 88 
2 Gene1 C 97 5 30 21 88 
3 Gene1 D 94 5 19 39 88 
4 Gene2 B 88 2 13 20 97 
5 Gene2 C 98 5 20 43 97 
6 Gene2 D 95 4 39 2 97 
7 Gene3 B 93 5 40 50 89 
8 Gene3 C 92 5 43 30 89 
9 Gene3 D 91 3 27 11 89 
10 Gene4 B 87 2 49 49 98 
11 Gene4 C 97 3 6 47 98 
12 Gene4 D 88 3 33 44 98 

然後,我通過最後一個分裂數字列:

dtm[,c(3:6)] <- dtm[,c(3:6)]/dtm[,'Avg.y'] 

    Gene Cond  Avg.x   SE  Val1  Val2 Avg.y 
1 Gene1 B 1.1022727 0.04545455 0.10227273 0.32954545 88 
2 Gene1 C 1.1022727 0.05681818 0.34090909 0.23863636 88 
3 Gene1 D 1.0681818 0.05681818 0.21590909 0.44318182 88 
4 Gene2 B 0.9072165 0.02061856 0.13402062 0.20618557 97 
5 Gene2 C 1.0103093 0.05154639 0.20618557 0.44329897 97 
6 Gene2 D 0.9793814 0.04123711 0.40206186 0.02061856 97 
7 Gene3 B 1.0449438 0.05617978 0.44943820 0.56179775 89 
8 Gene3 C 1.0337079 0.05617978 0.48314607 0.33707865 89 
9 Gene3 D 1.0224719 0.03370787 0.30337079 0.12359551 89 
10 Gene4 B 0.8877551 0.02040816 0.50000000 0.50000000 98 
11 Gene4 C 0.9897959 0.03061224 0.06122449 0.47959184 98 
12 Gene4 D 0.8979592 0.03061224 0.33673469 0.44897959 98 

最好使用grep避免數字索引:

dtm[, !grepl('Gene|Cond',names(dtm))] = 
    dtm[, !grepl('Gene|Cond',names(dtm))] /dtm[,'Avg.y'] 
> dtm 
    Gene Cond  Avg.x   SE  Val1  Val2 Avg.y 
1 Gene1 B 1.1022727 0.04545455 0.10227273 0.32954545  1 
2 Gene1 C 1.1022727 0.05681818 0.34090909 0.23863636  1 
3 Gene1 D 1.0681818 0.05681818 0.21590909 0.44318182  1 
4 Gene2 B 0.9072165 0.02061856 0.13402062 0.20618557  1 
5 Gene2 C 1.0103093 0.05154639 0.20618557 0.44329897  1 
6 Gene2 D 0.9793814 0.04123711 0.40206186 0.02061856  1 
7 Gene3 B 1.0449438 0.05617978 0.44943820 0.56179775  1 
8 Gene3 C 1.0337079 0.05617978 0.48314607 0.33707865  1 
9 Gene3 D 1.0224719 0.03370787 0.30337079 0.12359551  1 
10 Gene4 B 0.8877551 0.02040816 0.50000000 0.50000000  1 
11 Gene4 C 0.9897959 0.03061224 0.06122449 0.47959184  1 
12 Gene4 D 0.8979592 0.03061224 0.33673469 0.44897959  1 
+0

謝謝!這比我想要的要簡單得多,而且完成了這項工作。它確實出現在我的解決方案中,但我不知道如何使用合併來創建最後一列。 – phosphorelated

0

編輯:請注意,這是OP的問題的曲解。它所做的是將數據幀中的每列按照Cond=="A"的平均值進行標準化。如果有人關心這件事,留在這裏。感謝Agstudy。

你可以試試:

norm.vec <- colMeans(subset(my.df, Cond=="A")[-(1:2)]) 
my.df[-(1:2)] <- t(t(my.df[-(1:2)])/norm.vec) 

這種利用回收的(但是我們需要調換爲它工作)。 head(df)

# Cond Gene  Avg  SE  Val1  Val2 
# 1  A Gene1 0.9470752 0.6153846 0.89655172 1.6752137 
# 2  A Gene2 1.0473538 1.2307692 1.41379310 0.5811966 
# 3  A Gene3 1.0473538 1.5384615 0.44827586 1.6068376 
# 4  A Gene4 0.9582173 0.6153846 1.24137931 0.1367521 
# 5  B Gene1 1.0250696 0.3076923 0.06896552 0.6495726 
# 6  B Gene2 0.9582173 1.2307692 0.41379310 0.4444444 
+0

@Brodgie這是OP正在尋找什麼。即使我認爲這可能是一個很好的解決方案,也不需要使用colMeans。你應該只需要'Avg'列來構造norm.vec。 – agstudy

+1

@agstudy,LOL,謝謝你給我回答一個沒有問的問題的道具。我完全被列的名字拋棄!鑑於實際要求的內容,除非我對基因的順序和數量做了大量假設,否則我不認爲這個答案有效。 – BrodieG

0

這裏是我如何使用plyr包做:

library("plyr") 

ddply(my.df, .(Gene), transform, 
     Avg.norm = Avg/Avg[Cond=="A"], 
     SE.norm = SE/SE[Cond=="A"], 
     Val1.norm = Val1/Val1[Cond=="A"], 
     Val2.norm = Val2/Val2[Cond=="A"]) 

我把這個歸一化值到新列,但你可以很容易地覆蓋現有的。

相關問題