我有一个由
生成的数据集df
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))
看起来像
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
行除以&#34;周围&#34;的平均值。 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
对于SAM4
和SAM5
,avg2
将被计算为ratio1
和SRM2
个样本的SRM3
值的平均值。< / p>
对于SAM6
的假设id = 10
,avg3
将被计算为ratio1
报告的值SRM4
与假设{{1}之间的平均值之间的平均值带有SRM5
的样本。
请考虑:
id = 11
; 标识的样本计算avg
个值
SRM
个样本有许多不同的名称,没有共同的字符串; SRM
的距离可能会有所不同(有时为3行,4行甚至0行)SRM
列也需要类似的操作,但ratio2
代替b = 0.91
。这只会让我发疯。
答案 0 :(得分: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)
它似乎有效,但我认为最后两行有点混乱。你知道如何改进代码吗?