2014-01-13 69 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