2017-02-22 24 views
0

我具有由R:通過當某些條件滿足時,改變另一個值數據集中的除法值

df <- data.frame(
    id = seq(1:9), 
    sample = c("SRM1", "SAM1", "SAM2", "SAM3", "SRM2", "SAM4", "SAM5", "SRM3", "SRM4"), 
    ratio1 = rnorm(9, mean = 2, sd = 0.02), 
    ratio2 = rnorm(9, mean = 1, sd = 0.01)) 

產生的數據集df和看起來像

id sample ratio1 ratio2 
1 SRM1 2.0271 0.99915 
2 SAM1 2.0241 0.98810 
3 SAM2 1.9522 1.00300 
4 SAM3 1.9877 1.00343 
5 SRM2 1.9800 1.00522 
6 SAM4 2.0184 0.97788 
7 SAM5 2.0045 1.00549 
8 SRM3 1.9684 0.99129 
9 SRM4 2.0034 1.00310 

我不得不分割值在ratio1列的SRM列中報告了固定號碼a = 1.9。然後,我必須將ratio1列中SAM行中報告的值除以「周圍」SRM/a值的平均值。

舉一個例子:在id 1和5有兩個SRM樣本,我計算avg1 <- mean(2.2701, 1.9800)/a。此時我可以計算

df$ratio.corr <- rep(NA, 9) 
df$ratio1.corr[c(2:4)] <- df$ratio1[c(2:4)]/avg1 

對於SAM4SAM5avg2將作爲平均的ratio1值的SRM2SRM3樣本來計算。

對於假想SAM6id = 10avg3將被計算爲報道SRM4ratio1和假想SRM5樣品與即id = 11之間的平均。

請考慮以下因素:

  • 真實數據集有大約10000行;
  • avg對於以字符串SRM標識的樣本,總是會計算出值;
  • SRM樣品有許多不同的名稱,沒有共同的字符串;從連續SRM
  • 距離可以變化(有時是3,4或甚至0行)也需要
  • 類似的操作爲ratio2列,但與b = 0.91代替a

這只是讓我發瘋。

回答

0

我發現這個可能的解決方案:

library(data.table) 
a = 1.9 
b = 0.91 
df <- as.data.table(df) 

# SRMs 
srm <- grep("SRM", df$sample) 
# SAMs between consecutive SRMs 
sam <- diff(srm)-1 

# Splitting df in SRMs and SAMs 
df.srm <- df[srm][, id := 1:.N] 
df.sam <- df[-srm] 

# For each SAMs I write the IDs of the SRMs before and after it 
srm1 <- rep(df.srm$id[-length(df.srm$id)], sam) 
srm2 <- srm1 + 1 
df.sam <- df.sam[, ':=' (srm1 = srm1, srm2 = srm2)] 

# Calculating ratio1/a and ratio2/b 
df.srm[, ':=' (ratio1.a = ratio1/a, ratio2.b = ratio2/b)] 

# Calculating ratios for each SAMs divided by the average of srm1 and srm2 
df.sam$ratio1.ok <- df.sam$ratio1/((df.srm$ratio1.a[df.sam$srm1] + df.srm$ratio1.a[df.sam$srm2])/2) 
df.sam$ratio2.ok <- df.sam$ratio2/((df.srm$ratio2.b[df.sam$srm1] + df.srm$ratio2.b[df.sam$srm2])/2) 

這似乎工作,但我認爲最後兩行是有點亂。你知道如何改進代碼嗎?

相關問題