2014-01-13 112 views
2

我有一大組縮放因子,我希望將其應用於數據框,這些因子對於樣本來自的特定組以及特定於樣本的每個變量。我試圖爲這個問題構建一個最簡單的例子。按組和變量名稱縮放R數據框中的值

縮放因子

Batch A  B 
Q  1.01 1.31 
R  0.90 1.22 
S  1.04 1.09 

DATA

​​

這樣的話,比方說,一批Q採樣1將從23去的,10至23.23,13.1

我意識到有可能是在解決方案的某個地方適用於此,但我正在努力研究從哪裏開始。任何幫助非常讚賞:-)

scaling_factors_example<-data.frame(Batch=c("Q","R","S"),A=c(1.01,0.9, 1.04), B=c(1.31, 1.22, 1.09)) 

data_example<-data.frame(Batch=c("Q","Q","R","R","S","S"), A=c(23,22,27,26,22,24), B=c(10,11,12,13,14,15)) 

回答

4

馬克的回答即興(借用他的縮寫),除非它使用match,而不是合併,因爲這是經常爲N-1快得多加入:

d[, -1] <- d[, -1] * s[match(d[, 1], s[, 1]), -1] 

產生

# Batch  A  B 
# 1  Q 23.23 13.10 
# 2  Q 22.22 14.41 
# 3  R 24.30 14.64 
# 4  R 23.40 15.86 
# 5  S 22.88 15.26 
# 6  S 24.96 16.35 

match在第二個向量中找到第一個向量中值的位置,這有效地允許進行N-1合併,就像這裏的情況一樣。正如我指出的,它的速度更快,如果你有大的表要加入這可能無關緊要:

library(microbenchmark) 
microbenchmark(s[match(d[, 1], s[, 1]), -1]) 

# Unit: microseconds 
#  min  lq median  uq  max neval 
# 167.854 173.706 176.6315 181.019 279.025 100 

microbenchmark(merge(d[ ,1, drop=F], s, "Batch")) 

# Unit: microseconds 
#  min  lq median  uq  max neval 
# 983.353 1060.149 1068.195 1103.302 2181.004 100 

側面說明,如果你有大的表,你應該考慮data.table的合併,因爲這能更快比在match,在某些情況下。

+0

+1,提供更加靈活和快速的解決方案! –

5

它更容易,如果你去合併的方式,而不是使用申請家庭,我覺得(sscaling_factors_exampleddata_example

m <- merge(d[ ,1, drop=F], s, "Batch") 
d[-1] <- m[-1] * d[-1] 
d 

    Batch  A  B 
1  Q 23.23 13.10 
2  Q 22.22 14.41 
3  R 24.30 14.64 
4  R 23.40 15.86 
5  S 22.88 15.26 
6  S 24.96 16.35 

說明

merge爲您提供與包含每個條目的相應縮放因子的數據具有相同大小的數據幀。現在你可以簡單地乘以列。

+0

感謝您的迅速和有益的回覆:drop = F和合並功能是非常方便的提示;不過,我接受了BrodieG的回答,因爲我認爲速度在我的應用中可能很重要。 – bioinformagician